cosmin's profileCosmin's Hooking testifyPhotosBlogListsMore ![]() | Help |
Public folders
|
Thanks for visiting!
Cosmin's Hooking testifySecurity, Exchange, Kernel Mode Drivers, AntiSpam April 12 MAPI and .Net an Developer view – NOT Supported
The fact that MAPI is not supported with .Net. Turns out, while was mentioned several times, I’ve never devoted a topic to it. So here goes. Here are the articles which outlines the official support policies for MAPI and .Net, from both the Exchange and Outlook perspectives: Support policy for Microsoft Exchange APIs with the .NET Framework applications Support policy for Outlook APIs that are used in the .NET Framework environment A bit of history of this policy: When .Net was first announced, Developers were very excited, try every API supported and started figuring out how to invoke them from managed code.Were a series of KBs (never published) showing how to do pretty much everything with Simple MAPI, and had begun work developing a shim for Extended MAPI. But then the bugs started coming in. Are early adopters using MAPI and CDO 1.21 from .Net who were seeing strange error codes, memory leaks, and crashes. Investigating these, and eventually asked Microsoft development support for their opinion. Asking the Exchange team first, about their implementation of MAPI and CDO, and whether could provide support for using either in managed code. The senior developer who not only owns, but who wrote a large portion of MAPI led the investigation. His conclusion: MAPI was not designed or tested to run in a managed environment, and cannot provide support for doing so. A short (incomplete) list of problems he uncovered in his investigation:
Same question to Outlook, and given the shared development history of the Outlook and Exchange implementations of MAPI, the Outlook development team also concluded they would be unable to support MAPI or CDO with .Net. Now – what does it mean to say it’s not supported so better Native support for Mapi/CDO or now even better – CLI to push it up to Managed interop. February 21 Linus Torvald blog
right is that person that you suppose and have a blog http://torvalds-family.blogspot.com/ and opinions about one Microsoft product http://torvalds-family.blogspot.com/2009/01/fantastic.html :) Windows Web Services API beta release
i just read the post of Nikola Dudar that first version of Windows Web Service api is available, great news, for native interoperability in enterprise applications. I was in his session @PDC in LA regarding this and was amazing. what’s is this about , you can create native webservices and webervice clients: // Create a channel
hr = WsCreateChannel(
WS_CHANNEL_TYPE_REQUEST,
WS_HTTP_CHANNEL_BINDING,
NULL,
0,
NULL,
&channel,
error);
if (FAILED(hr))
{
goto Exit;
}
hr = WsCreateMessageForChannel(
channel,
NULL,
0,
&requestMessage,
error);
if (FAILED(hr))
{
goto Exit;
}
hr = WsCreateMessageForChannel(
channel,
NULL,
0,
&replyMessage,
error);
if (FAILED(hr))
{
goto Exit;
}
For reference documentation for the API, check out MSDN site http://msdn.microsoft.com/en-us/library/dd430435(VS.85).aspx. here are the downloads x86 – http://connect.microsoft.com/WNDP/Downloads/DownloadDetails.aspx?DownloadID=16646 Windows XP SP2 and SP3 X86 English – http://connect.microsoft.com/WNDP/Downloads/DownloadDetails.aspx?DownloadID=16651 X64 English – http://connect.microsoft.com/WNDP/Downloads/DownloadDetails.aspx?DownloadID=16662 Windows Server 2003 SP2 and R2 SP2 February 15 Managed Interop. – Printer ports
At work, i had to find a way to create new TCP/IP printer ports on a remote print server from the .NET code of my application. I couldn’t use WMI, so i had to find something else. Luckily, the XcvData Windows function does just that. Unfortunately, it is a royal pain in the ass to use and there’s not a lot of documentation available on how to use it. And i certainly didn’t find anything on how to call it from .NET code. here is the Native way : HANDLE hXcv=NULL;
DWORD dwFuncResult;
PRINTER_DEFAULTSW Default ;//= {NULL, NULL,SERVER_ACCESS_ADMINISTER };
Default.pDatatype = NULL; Default.pDevMode = NULL; Default.DesiredAccess = SERVER_ACCESS_ADMINISTER;
if (pServerName = ConstructXcvName(NULL, L"Local Port", L"XcvMonitor")) { dwFuncResult = OpenPrinterW((PWSTR) pServerName, &hXcv, &Default);
if (dwFuncResult && hXcv!=NULL)
{
DWORD dwStatus, cbInputData =100,cbOutputNeeded = 0;
PBYTE pOutputData = new BYTE [ cbInputData];
if(XcvData(hXcv, L"AddPort", (PBYTE) m_strPortName,
sizeof(WCHAR) * (wcslen(m_strPortName) + 1), //
pOutputData, cbInputData , & cbOutputNeeded, &dwStatus))
{
if(dwStatus == ERROR_SUCCESS)
{
}
else if (dwStatus == ERROR_ALREADY_EXISTS)
{
m_strErr.Format("Add Port Failed %d."(::GetLastError())); OutputDebugString(m_strErr); } else { m_strErr.Format("Add Port Failed %d." (::GetLastError()));
OutputDebugString(m_strErr);
}
}
else
{
m_strErr.Format("XcvData Add Port Failed %d.",::GetLastError()));
OutputDebugString(m_strErr);
m_bReturn=FALSE;
}
delete pOutputData;
ClosePrinter(hXcv);
}
else
{
m_strErr.Format("Open printer Failed %d.",(::GetLastError()));
OutputDebugString(m_strErr);
m_bReturn=FALSE;
}
}
else
{
m_strErr.Format("Open port Failed %(::GetLastError()));
OutputDebugString(m_strErr);
m_bReturn=FALSE;
}
}
Just looking at that makes me feel bad for everyone who’s ever had to code against Windows API’s. Anyway, according to the documentation, the first parameter (hXcv) should be a handle to the print server (which you can retrieve with a call to OpenPrinter), the second parameter (pszDataName) has to be “AddPort” if you want the function to create a new port. And then comes the fun part… the third parameter (pInputData) should be a pointer to a PORT_DATA_1 structure and the fourth parameter has to contain the size in bytes of the PORT_DATA_1 structure you passed as the third argument. The other parameters can be ignored (nice API design btw) except for the last one, which is an out parameter that will return a numeric code which will indicate either success or the cause of the failure. I had a lot of problems trying to pass a pointer to a valid PORT_DATA_1 structure. The structure looks like this: typedef struct _PORT_DATA_1 {
WCHAR sztPortName[MAX_PORTNAME_LEN];
DWORD dwVersion;
DWORD dwProtocol;
DWORD cbSize;
DWORD dwReserved;
WCHAR sztHostAddress[MAX_NETWORKNAME_LEN];
WCHAR sztSNMPCommunity[MAX_SNMP_COMMUNITY_STR_LEN];
DWORD dwDoubleSpool;
WCHAR sztQueue[MAX_QUEUENAME_LEN];
WCHAR sztIPAddress[MAX_IPADDR_STR_LEN];
BYTE Reserved[540];
DWORD dwPortNumber;
DWORD dwSNMPEnabled;
DWORD dwSNMPDevIndex;
} PORT_DATA_1, *PPORT_DATA_1;
As you can see, the struct contains a couple of Unicode character arrays and even a byte array. Defining a struct in C# that could be marshalled to this turned out to be the tricky part in getting this stuff to work. But first of all, we needed to be able to call the OpenPrinter function to retrieve a handle to the print server where we need to create the new printer port:
First of all, the struct has to have Sequential as its LayoutKind, and each string must be marshalled as a unicode string (.NET strings are unicode by default, but when marshalled to native code they are converted to ANSI strings, so the CharSet setting is definitely required). Then, for each array in the original struct, you need to make sure our string is converted to an array of the expected size. Marshalling those strings as ByValTStr and setting the SizeConst parameter did the trick there. Then there’s the byte array in the original struct. The function expects there to be a byte array of 540 elements. Marshalling it as ByValArray and setting the SizeConst makes that work as well. Right, now we have the structure, so we still need a way to call the XcvData function: [DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Unicode)] public static extern int XcvDataW (IntPtr hXcv, string pszDataName, IntPtr pInputData, UInt32 cbInputData, out IntPtr pOutputData, UInt32 cbOutputData,out UInt32 pcbOutputNeeded, out UInt32 pdwStatus); Notice how the DllImport attribute has its CharSet parameter set to unicode as well. If you don’t do this, the function call will crash your app (can’t even catch an exception) because it expects pszDataName to be a unicode string and as mentioned earlier, without specifying CharSet.Unicode it would’ve been marshalled to an ANSI string. Happy times. Anyways, creating a TCP/IP printer port on a remote server is now as simple as this: IntPtr printerHandle;
InteropStuff.PrinterDefaults defaults =
new InteropStuff.PrinterDefaults { DesiredAccess = InteropStuff.PrinterAccess.ServerAdmin }; InteropStuff.OpenPrinter(@”\myPrintServer,XcvMonitor Standard TCP/IP Port”, out printerHandle, ref defaults); InteropStuff.PortData portData = new InteropStuff.PortData { dwVersion = 1, // has to be 1 for some unknown reason dwprotocol = 1, // 1 = RAW, 2 = LPR dwPortNumber = 9100, // 9100 = default port for RAW, 515 for LPR dwReserved = 0, // has to be 0 for some unknown reason sztPortName = “IP_198.23.124.15″, sztIPAddress = “198.23.124.15″, sztSNMPCommunity = “public”, dwSNMPEnabled = 1, dwSNMPDevIndex = 1 }; uint size = (uint)Marshal.SizeOf(portData); portData.cbSize = size; IntPtr pointer = Marshal.AllocHGlobal((int)size); Marshal.StructureToPtr(portData, pointer, true); try { IntPtr outputData;UInt32 outputNeeded;UInt32 status; InteropStuff.XcvDataW(printerHandle, “AddPort”, pointer, size, out outputData, 0, out outputNeeded, out status); } finally { InteropStuff.ClosePrinter(printerHandle); Marshal.FreeHGlobal(pointer); } February 01 Application hosting on Windows 2008 Core –part 2
Microsoft is working on official version of .NET and PowerShell for Server Core R2 installations, the instructions you can use at your own risk, etc., etc. The problem is that it only ships with traditional cmd.exe and not PowerShell. To make things worse neither PowerShell nor .NET as they are today can be installed on such systems. Alex Kibkalo and a great post by Artem Pronichkin on installing .NET on Server Core that makes this task easier. Basically the whole procedure consists of just four main steps:
1. Microsoft Visual C++ 2005 SP1 Redistributable PackagesAfter that, copy these files to your Server Core computer and simply run them there. If your Server Core is 32-bit - just run 2. .NET FrameworkThis is the most tricky part. PowerShell needs .NET 2.0 and .NET 2.0 is supposed to be a component of Windows Server 2008 so we will have to get a package of the framework which can get installed on such a system. To accomplish that we will:
2.1. Download .NET: Go to Microsoft’s web site and download full redistributable package of .NET 3.5. 2.2. Unpack the file: After the script executes, the 2.3. Install Orca: This is great but unfortunately you cannot just install the files because the MSIs are specifically checking for Windows version. So now we need to disable this check. To do this we will use Microsoft’s Note: This all needs to be done on a regular, not Server Core, machine. We will copy the results of our Orca operations to the Core box later on. If you don’t have Orca, follow these steps to download it: c. After the installation completes, go to 2.4. Tweak the setup: Now its time to do some patching. e. Save changes (either to that same MSI or a transform file.) 2.5. Install .NET Copy the files (the whole folder) to your core machine and start the MSI via this command line (note that you need to use msiexec in order to pass the If you saved a transformed file and are running 64-bit version you will probably run: On x86 without a transform that would be:
That’s it. Now we have .NET installed and can go to the final step - PowerShell installation! 3. Windows PowerShellThere is no PowerShell v1 setup for Windows 2008 (again, because it is supposed to be a component) but you can actually download and install the CTP (note: this is a pre-beta code - not for production use). PowerShell v2 CTP2 is available from Microsoft’s downloads page. Download the version you need, copy the msi over to the Server Core box and simply run the msi. 4. Now you can start PowerShell!Just run: And you will see the prompt change to: That’s it. Now you are among the first geeks in the Universe to have PowerShell on Server Core!
|
|
|||||||
|
|