Dhawan : The One

  • When custom EAP authentication dll calls EapPeerInvokeInteractiveUI for wireless LAN 802.1x …

    When custom EAP authentication dll calls EapPeerInvokeInteractiveUI for wireless LAN 802.1x, a dialog box is displayed and a balloon is popped-up on Windows Vista machine. And the developer of the EAP authentication dll, needs to suppress dialog box and balloon.

    The scenario is like - You are using custom EAP authentication dll which call EAPHost EapPeerInvokeInteractiveUI function to display a custom dialog box to the user to gather user's credentials. On Windows Vista, there is an additional dialog box displayed by system to get user consent whether they want to "Enter/select additional log on information" or "Connect to a different network" .  Clicking on "Enter/select additional log on information" on the consent dialog, the actual dialog is displayed. You want to suppress this intermediate system consent dialog box and possibly balloon as well.

    There is no way to suppress the dialog and balloon on Windows Vista machine, this is by design. On Windows 7, the dialog box has been eliminated by design but balloon is there when the call to EapPeerInvokeInteractiveUI will be made by EAP dll. This is true for profile based authentication and non-profile based authentication if authentication requires user input. 

    Nitin Dhawan

    Windows SDK – Microsoft

  • Introduction to IMAPI

    In recent past, I have seen few question coming to me asking, “How do I write data on the CD/DVD disk programmatically?” . During my research, I have good introduction to the interfaces available on Windows for burning CD/DVD programmatically that I want to share with all.

    There are two basic way to burn CD/DVD. One question can come pretty early, How does Windows OS in-built functionality works? On Windows XP onwards ( could not check on Windows 2000 or earlier, probably there is none ) we can burn the disc by dragging the files/folders on to the disc. OS does it with the shell interface ICDBurn Interface. If you want to burn the files/folders in your program you can use ICDBurn interface but before calling ICDBurn::Burn Method, you need to copy the files/folders in a specific location called CD Staging Area. Once your application selects the files/folders to be written in the CD/DVD and copied to the CD Staging area, calling ICDBurn::Burn Method will burn the CD/DVD, same as OS and delete the files from that location automatically. CD Staging area can be determined by the application by the information available in MSDN documentation as below --

    The staging area has a default location of %userprofile%\Local Settings\Application Data\Microsoft\CD Burning. Its actual path can be retrieved through SHGetFolderPath, SHGetSpecialFolderPath, SHGetFolderLocation, SHGetSpecialFolderLocation, or SHGetFolderPathAndSubDir by using the CSIDL_CDBURN_AREA value.

    Other way to burn CD/DVD is using Image Mastering API or IMAPI in short. IMAPI comes in two versions IMAPIv1 and IMAPIv2. IMAPIv1 is available for application to be used on Windows XP and Windows Server 2003 and IMAPIv2 is available on Windows Vista onwards, in-box. You can also get the IMAPIv2 available on Windows XP and Windows Server 2003 after installing a package, links and information are below--

    What's New

    IMAPI 2.0 is included in Windows Vista. Enabling the same functionality for Windows XP and Windows Server 2003 requires the installation of the KB932716 update package.

    After installing Description of the Image Mastering API v2.0 (IMAPIv2.0) update package that is dated June 26, 2007 on Windows XP or  Windows Server 2003, application can use the interfaces exposed by IMAPIv2.

    Note – Before burning any CD/DVD please see through documentation that which filesystem you want the IMAPI interfaces to be written on the disc? There are few options available like ISO9660, Joliet and UDF.

    Next, few links to be shared for IMAPIv1 interfaces available.

    IDiscMaster Interface

    IDiscMaster::Open Method

    IDiscMaster::RecordDisc Method

    Next, few links to be shared for IMAPIv1 interfaces available.

    IDiscMaster2 Interface

    IDiscRecorder2 Interface

    Also, IMAPIv2 has multisession support and interfaces are available.

    Samples- While there are code snippet sample available on MSDN documentations of the interface/method, there are 2 complete sample applications available in Windows SDK for Vista ( onwards ). Sample locations are below after you install Windows SDK on the dev machine ---

    %program files%\Microsoft SDKs\Windows\v6.0\Samples\WinBase\imapi\imapi2sample

    %program files%\Microsoft SDKs\Windows\v6.0\Samples\WinBase\storage\IBurn

    While imapi2sample is native code in C++, IBurn sample is managed in C#. Please refer to the samples for more understandings of the IMAPI, that can give good start if you want to develop a feature/application for CD/DVD burning.

     

    Nitin Dhawan

    Windows SDK – Microsoft

  • Send multiple files to FAX in one call

    There might be a need that an application need to send multiple files to the FAX server in one single call. While IFaxDocument::ConnectedSubmit Method allows to send a single file to FAX in one call, IFaxDocument2::ConnectedSubmit2 Method can be used to send multiple files. The IFaxDocument2::ConnectedSubmit2 Method can be used only on Windows Vista and later versions.

    As in online documentation, the syntax to mention multiple files name/path is as below--

    To illustrate plErrorBodyFile, here is an example: The following list of files is submitted as the value of IFaxDocument2::Bodies:

    "MyTextFile.txt;AnotherTextFile.txt;MyWordFile.doc".

    Also in the documentation it is mentioned that the .pdf format is not supported by the interface. So if a file with .pdf is supplied to be sent to the FAX server, method will fail with error 2.

    To understand the usage of the interface/method, you can use “SendFax” sample in Windows SDK for Vista in below path--

    %program files%\Microsoft SDKs\Windows\v6.0\Samples\NetDs\Fax\SendFax

    SendFax sample is available in C++, C# and VB.NET languages.

    Nitin Dhawan

    Windows SDK – Microsoft

  • Get the MAC address of a machine/device whose IP Address is known

    Sometime you may be in a situation to get the MAC address of a machine/device whose IP Address is known. Conventional way like using NetBios or GetAdaptersInfo or GetAdaptersAddresses can give the MAC address of the same machine where the code is running, does not solve the purpose because the machine where the code is executing is not the one for which you have the IP Address and need MAC address. You need API like below --

    GetmeMACAddress_IgaveYouIP(&Mac,&IP);  , then life will be easy.

    It was clear that ARP protocol will be used for this purpose, but I need to find the programmatic way.

    There is a command “arp” that does it, so definitely it is possible to do that. ( arp –a <IP Address> ) will give the MAC address of the machine/device.

    Initially when I searched on Internet to find the answer, there were some manual ways and couple of tools, but I want to program it myself, so not of much use.

    Later, going though the documentation of Network functions on MSDN site, SendARP Function from IpHelper library, was looking closer. Testing with the sample application available on MSDN page, it works just fine and solve the purpose.

    Please read the Remarks section of the API documentation.

    Nitin Dhawan

    Windows SDK – Microsoft

     

  • Enable or Disable “Enable write caching on disk” behavior on disk

    Couple of times I got a question to <Enable or Disable “Enable write caching on disk” behavior on disk>, How to do it programmatically on Windows? When I got this question for the first time, it was tough but doing research I was able to solve it and it works well. Every next time, it was easy :)

    In this post, I will not discuss what exactly this feature does and pros and cons of enable/disable it. I will only discuss, How to do it.

    disk_cache

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    You can do it manually as well.

    #1, Select a volume from Explorer, right click –> Properties

    #2, Select “Hardware” tab, select disk and click “Properties” button

    #3, Select “Policies” tab.

    #4, Check/Uncheck to enable/disable “write caching on the disk”

     

    To do it programmatically.

    #1, You will need to work with below APIs and control code.

    CreateFile Function

    DeviceIoControl Function

    DISK_CACHE_INFORMATION Structure

    IOCTL_DISK_GET_CACHE_INFORMATION Control Code

    IOCTL_DISK_SET_CACHE_INFORMATION Control Code

     

     

    The information is actually gets stored in below registry key, I would not recommend to look for the value in the key directly and design your application on that. It may change in future.

    HKLM\SYSTEM\CurrentControlSet\Enum\IDE\Diskxxxxxxxxxxxx\DeviceParameters\Disk
    Key : UserWriteCacheSetting

    where xxxxxxx is manufacturer information.

     

     

    The sample will look like below. This is just a test sample and provided only to demonstrate the functionality. You might need to use put more error handling and test the code as you do for regular production environment code.

    //////////////////////SAMPLE CODE 
    ///////////////////////////////////////////////////////////
    #define _WIN32_WINNT 0x0503
    
    #include <windows.h>
    
    DISK_CACHE_INFORMATION info;
    DISK_CACHE_INFORMATION rinfo;
    
    
    void main(void)
    {
        DWORD rr;
        HANDLE hDevice;
        DWORD err;
        DWORD returned;
    
        hDevice = CreateFile("\\\\.\\C:", // drive to open
                    GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_WRITE | FILE_SHARE_READ, 
                    // share mode
                    NULL, // default security attributes
                    OPEN_EXISTING, // disposition
                    FILE_ATTRIBUTE_SYSTEM, // file attributes
                    NULL); // do not copy file attributes
        if(hDevice==INVALID_HANDLE_VALUE)
        {
            return;
        }
    
        rr = DeviceIoControl(hDevice,IOCTL_DISK_GET_CACHE_INFORMATION,NULL,
                            0,(LPVOID)&info,(DWORD)sizeof(info),(LPDWORD)&returned,    (LPOVERLAPPED)NULL);
        if (!rr)
        {
            err = GetLastError();
            return;
        }
    
        info.WriteCacheEnabled = true;
        info.ReadCacheEnabled = false;
        info.DisablePrefetchTransferLength = 1;
    
        rr = DeviceIoControl(hDevice,IOCTL_DISK_SET_CACHE_INFORMATION,(LPVOID)&info,(DWORD)sizeof(info),
                            NULL,0,(LPDWORD)&returned,(LPOVERLAPPED)NULL);
        if (!rr)
        {
            err = GetLastError();
            return;
        }
    
        rr = DeviceIoControl(hDevice,IOCTL_DISK_GET_CACHE_INFORMATION,NULL,0,
                            (LPVOID)&rinfo,(DWORD)sizeof(rinfo),(LPDWORD)&returned,(LPOVERLAPPED)NULL);
        if (!rr)
        {
            err = GetLastError();
            return;
        }
    
        CloseHandle(hDevice);
    }
    //////////////////////SAMPLE CODE 
    ///////////////////////////////////////////////////////////

    *Note—Not all disks and controllers implements write disk caching, I have not tested the behavior or any such disk yet, so behavior is unknown to me.

     

    Nitin Dhawan

    Windows SDK - Microsoft

     

  • Check membership of a group from user’s process access token

    Question may be, I need to check If the user belong to a particular group or not? There are NetUser* APIs available in NetApi32.lib to list the groups a user belong to a group. You can actually check but then you will need to compare the string of the group you are interested to check and the list returned by the NetApi. Please see the sample available on NetUserGetGroups Function. This approach can be acceptable in some scenarios, but may not work in other.

    In a domain environment, there are two domains A and B and have trust relationship in between them. An user of domain A, logged on to a machine in domain B. The application running as domainA\UserA, calls NetUserGetGroups to get the global groups of the user, for any purpose. Generally it should work fine and works fine, I have tested it on many environments, but this approach may fail as well. If the domain where the query should go, has not opened the port ( by firewall ) the API is going to use, then API will not able to get the list of groups for the user. To solve the problem, you need to open the port, which may not be possible because the management of DC on other end not want to do it at all. Now, How to solve it?

    When the user logs on providing credentials, authenticated by the AD on DC successfully, gets the logon token, profile is loaded, desktop is created etc etc. The logon token has the information about the user, for what groups it belong to. When user launched any application, it will be launched by this logon token. So, the information about the groups is already within the process itself. You can check it with a tool called whoami (/all) in Windows directory. If we have any API to read this list then we don’t have to go to network again or use NetAPIs. GetTokenInformation Function can be used to list the groups and for other purposes. Is there an API to actually check if the user belong to a particular group? CheckTokenMembership Function can be used for this purpose. API does not look for the group by its name, but by SID. If we have the name, we can convert to SID and pass to CheckTokenMembership. Demo sample code will look like below--

    #include<windows.h>
    #include<Sddl.h>
    #pragma comment(lib,"Advapi32.lib")
    int main (int argc, CHAR * argv[]) 
    {
    BOOL bStatus;
    BOOL bIsMember;
    SID_NAME_USE sid_name_use;
    DWORD dwDomainNameSize;
    TCHAR tszDomainName [256];
    PSID pSidToCheck;
    DWORD cbsid=1024;
    LPBYTE pPDC = NULL;
    HANDLE hToken;
    
        if (argc != 2){
            printf("\nUSAGE: %ls grouptocheck\n\n", argv[0]);
            return 1;
        }
    
        bStatus = OpenProcessToken(OpenProcess(GENERIC_ALL, FALSE, GetCurrentProcessId()), GENERIC_ALL, &hToken);
        if (!bStatus){
            printf("OpenProcessToken failed: %u\n", GetLastError());
            return 1;
        }
    
        pSidToCheck = malloc (cbsid );
        dwDomainNameSize = sizeof(tszDomainName);
        bStatus = LookupAccountName(
            NULL,       // address of string for system name
            argv[1],      // address of string for account name
            pSidToCheck,      // address of security identifier
            &cbsid,      // address of size of security identifier
            tszDomainName,      // address of string for referenced domain 
            &dwDomainNameSize,      // address of size of domain string
            &sid_name_use       // address of SID-type indicator
        );
    
        if (!bStatus){
            printf("LookupAccountName failed: %u\n", GetLastError());
            return 1;
        }
    
        bStatus = CheckTokenMembership(/*hToken*/ NULL, pSidToCheck, &bIsMember);
        if (!bStatus){
            printf("CheckTokenMembership failed: %u\n", GetLastError());
            return 1;
        }
    
        if (bIsMember)
            printf("The user is a member of the group.\n");
        else
            printf("The user is NOT a member of the group.\n");    
        
        return 0;
    
    }

    Nitin Dhawan

    Windows SDK - Microsoft

  • Troubleshoot thread data race conditions in multithreaded environment: Chess

    Someone pointed me to look at this tool and see if there is any equivalent we have already or not. I looked at it and found it interesting. I have not explored this tool yet, but looks like it will be very helpful in debugging complex multithreaded applications and found the bug in early stages of the software development.This is CHESS, new project from Microsoft Research. The initial walkthrough on the pages, Chess can be integrated in Visual Studio environment as well. Chess works both native and managed code.

    CHESS Downloads

    CHESS: Find and Reproduce Concurrency Heisenbugs

    The CHESS scheduler – the key to finding concurrency bugs

    Also, installation of Chess provides significant amount of samples and tests to start with.

    Explore Chess !!!

     

    Nitin Dhawan

    Windows SDK - Microsoft

  • Slimmest way to call an exported function of unmanaged dll from a managed C# application

    Many times I came to situation that someone don’t know a good way to call an exported function of unmanaged dll from a managed application C# or VB. Person might not have any working knowledge of unmanaged dll, if they are required to create one.

    I am writing this post just to demonstrate, how to create a unm

    anaged dll and then export a function from it and call that function from the managed C# application.

    Create unmanaged dll to export a function

    First of all, I create a dll project that exports symbols. I will get the default template project which is ready to export a function, but I will create my own function.

    int MyWin32Function()
    {
        return 22;
    }

    If the declaration of the function is int MyWin32Function(); , then it will not be exported from the dll. You can check it from the dumpbin utility or Dependency Walker tool. How to make function exportable/visible to application? __declspec(dllexport) will be used to mark the function exportable. If the function declaration looks like below -__declspec(dllexport) int MyWin32Function(); , Is it exportable? Now if you compile it again and see from dumpbin, you see that the function is exported, but the name of the function is decorated. MyWin32Function will look like ?MyWin32Function@@SoMeChArS. This name decoration is because of name mangling of C++ compiler. It is not possible from the application to call the function with this name, the exported function from dll should be in human readable form, which is convenient, easy to document and easier to use. So, now the problem is, function is exported but with name decoration. We will need to eliminate name decoration so that application can use it easily. extern "C" will be helpful here, asking the C++ compiler to compile as C and no name decoration. Now, function declaration will look like below --

    extern "C" __declspec(dllexport) int MyWin32Function();

    The dll is ready to be used with exported MyWin32Function. Now, we need to call it from C# application.

     Now, you will need to call a unmanaged function from custom dll from a managed app, C#, need P/Invoke. I have discussed about the P/Invoke in my previous post. You can download P/Invoke Interop Assistant tool. You will need to create the signature of MyWin32Function(). I will use the declaration of my function in the tool and create a signature.

    pinvoke

     

    For simplicity, I will use the code in same class. Copy below code to C# application.

    /// Return Type: int
    [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint = "MyWin32Function")]
    public static extern int MyWin32Function();

    I will need to change the dll name to my dll name rather than <Unknown>.  

    /// Return Type: int
    [System.Runtime.InteropServices.DllImportAttribute("MyWin32Dll.dll", EntryPoint = "MyWin32Function")]
    public static extern int MyWin32Function();

     Now, You can call this function from C# application below-

    int a = 0;
    a = MyWin32Function();
    Console.WriteLine("returned from dll {0}",a);

    To pass parameters from managed application to unmanaged dll function, you will need to work on marshalling the data structures.

    Nitin Dhawan

    Windows SDK - Microsoft

     

  • Platform Invoke

    Someone asked me, "Why you are so unmanaged?" I said, "Because I work in unmanaged code." and burst into laughter. The gentleman could not understand why I am laughing, but said, "Sometimes you are managed." I could not control myself to laugh and said, "Because sometimes I work in managed code." The gentleman continued to ask, "How do you do that from unmanaged to managed?" Oh My God, "Platform Invoke" I said and keep laughing for few minutes. The gentleman was from Finance domain, so later I explained him the meaning of unmanaged, managed and its conversion in an abstract way. I got an idea to write a blog post about what I know about Platform Invoke.

    Before the advent of Microsoft .NET Framework, the code we used to write in C/C++ language was unmanaged and with .NET Framework the code we write in .NET language ( C#/VB/VC++) is managed. Why the code written in .NET is managed? Because, as a simplest example, when we allocate a memory for any object in .NET, programmer is not responsible to de-allocate/release it, it will be taken care by CLR/GC, so managed code, but in legacy/native programming, if we do the same, we are leaking memory. Programmer is responsible to do this, there is no CLR/GC, hence unmanaged code.

    The post is not to discuss any of the .NET feature and compare it with unmanaged stuffs. The article is about Platform Invoke. What is it and how do we do it?

    .NET Framework class library provides a set of classes to the developers of .NET applications to use it and build applications around it. The class library, internally uses native Win32 API calls to perform the actual task. Sometimes, you will be stuck If you want to do a particular task in your .NET application and there is no class that provides this functionality, It can only be done by a native Win32 API call, e.g. LogonUser(). There is no equivalent class/method to LogonUser() in .NET Framework class library. What will you do? Platform Invoke.

    How do I convert a Win32 API to its equivalent P/Invoke signature?

    There are couple of ways to do this. First is, Learn P/Invoke, write code and convert API to its .NET equivalent and then call from .NET managed code.

    There has been large amount of text available to learn P/Invoke. Microsoft and MSDN sites have many documents available, several websites offers tutorials. There are several blogs that talk about the various aspects of P/Invoke. I will try to give references to some of the articles at the end of this post.

    There are tools available for this purpose. Selecting the name of Win32 API or structure, the tool gives the P/Invoke signature of the API.

    Tool from CLR team - BCL Team Blog : P/Invoke Interop Assistant [Justin Van Patten] and download - Managed, Native, and COM Interop Team - Release: PInvoke Interop Assistant

    Links of interest--

    BCL Team Blog

    Comments on: The P-Invoke Interop Assistant

    CLR Inside Out: Marshaling between Managed and Unmanaged Code

    CLR Inside Out: Best Practices For Managed And Native Code Interoperability

    MSDN Magazine: CLR Inside Out

    Managed And Native Code Interoperability - Bing

    Platform Invoke Tutorials - Bing

     Nitin Dhawan

    Windows SDK - Microsoft

  • Working with Sysinternal tools -1

    Windows Sysinternals: Documentation, downloads and additional resources provides a set of tools to get information about various functionalities on the system. The area of information include , process running on the system, file operations, registry operations, TCP/IP related tasks, security etc. The complete list of the tools available can be found here, Sysinternals Utilities. Though there are separate web-pages to view the introduction of each tool and download the tool, there is a dedicated page to download all the tool at once, Sysinternals Suite .

    Sysintenals Live, Sysinternals Live is a service that enables you to execute Sysinternals tools directly from the Web without hunting for and manually downloading them. Simply enter a tool’s Sysinternals Live path into Windows Explorer or a command prompt as http://live.sysinternals.com/<toolname> or  \\live.sysinternals.com\tools\<toolname>.

    You can view the entire Sysinternals Live tools directory in a browser at http://live.sysinternals.com.

    The tools available through sysinternals are very helpful in various troubleshooting scenarios, and I use some of them on daily basis. Here I will try to explain my understanding about the tool and How to I get a particular information through them. It is not possible to demonstrate all of them at once, so this blog-post will get updated over-time whenever I have something to add or edit to it.

    Process Explorer

    Process Explorer is similar to Windows Task Manager, but shows more information and has extra functionalities to display more information about a process. On display of all the running processes, rather than showing the list of processes, it shows them as tree structure. With tree structure, it is easy to identify which process is parent process and which is child process. For example, If you launch cmd.exe from Start->Run, you will see that the Explorer is the parent process of cmd.exe .

    The other cool thing I like about Process Explorer is, it give the handle information, which are held by the process, with the type of the handle and which different dlls are loaded in the process address space and their path. It is very helpful in certain scenarios. The type of handle may be, File, Event, Mutex, Registry, Process etc etc.

    How to view handles for a process?

    View-> Lower Pane view->Handles , there will be a windows in lower half of the process explorer. Select a process from top windows, to view its handles.

    clip_image002 

    It get refreshed frequently, when a handle is created or deleted, it displays with green or red color.

    How to view Dlls loaded within a process?

    View-> Lower Pane view->Dlls , there will be a windows in lower half of the process explorer. Select a process from top windows, to view its loaded dlls.

    clip_image004

    There is no 64bit version of process explorer, so how a downloaded version which is 32 bit binary can walkthrough the 64 bit process address space and list all the dlls? This is solved by process explorer by a trick. I would assume, When process explorer is launched on a 64bit machine as a 32 bit binary, it checks through it code if it is running on a 64bit machine. If yes, it launches a 64 bit binary from within a 32 bit binary. As below—

    clip_image006

    And procexp.exe has a handle to the process as well.

    clip_image008

    The 64 bit exe will get deleted when process explorer is closed.

    Search is a vast business today and an important feature for any product. Process Explorer has a search only for handles or dlls, in all the processes. Standard Ctrl+F will give below dialog. The Find feature has always saved a lot of time for me, to pin point the exact process, rather than search manually for each process.

    clip_image010

    Help file is available for Process Explorer.

    TCPView

    TCP View is another tool which I use frequently to troubleshoot issues with Network programming. Often, it is needed to know that which port has been used by which process and with protocol and who is at the other end. While the same can be retrieved by netstat , but TCP view provides this information in GUI format and with refreshing screens. It is easy to view the behavior of the connections with TCP View in their different states.

    clip_image012

    The IP Address can be resolved in machine names as well through options menu.

    The same can be achieved by your own program as well using below APIs.

    GetExtendedTcpTable Function (Windows) and GetExtendedUdpTable Function (Windows).

    Help file is available for TCPView.

    Process Monitor

    Process Monitor is another very popular tool which is widely used. Initially there were tools like Filemon and Regmon but later integrated as Process Monitor. Filemon was used for tracing file related operations and Regmon was used for registry related operations. Now, with Process monitor, we have file and registry related operation in one tool and added network and process related operations. As a simple example, if a file has been created, opened, read, write, close or delete on file system, process monitor can record all these activities and can show the details with time, process name, which operation, on which file, the result of the operation and the details of the operation. The same applies to the registry activity. The cool point is, it can show that which threadID of a process has actually performed this activity.

    clip_image014

    Using Filter menu, you can restrict your capture, all activities by a particular process, all activities on a particular file or all activities by a particular process on a particular file. It has a lot of filters that can be applied to capture only what we want. Generally I get the complete capture from customer’s site, get the files and then apply needed filters here. Applying the correct set of filters will exactly show you what you want to see in the capture. Network activity can also be monitored from send or receive protocol packets, but I generally used Network Monitor from Microsoft.

    Help file is available for Process Monitor.

    VMMap

    The other tool is VMMap. VMMap is for Virtual Memory Map. VMMap is used to walk through the virtual address space of the process when selected and gathers the information about which memory is used for which purpose, displays with addresses in different colors. VMMap is helpful to look inside the process, and track any changes.

    clip_image016

    By default it displays the “Total” virtual memory in the lower pane. If you want to see only the loaded images (dlls), then you can select the “Image” from the upper pane list and it will convert as below—

    clip_image018

    Help file is available for VMMap.

    Nitin Dhawan

    Windows SDK - Microsoft

  • How to setup breakpoint programmatically in source code?

    Sometimes, you might be in a situation when you want to break in your code at a certain location. You might be trying to put a message box or getch() kind of method for that. There is a direct code to do that, through assembly language.

    int _tmain(int argc, _TCHAR* argv[])
    {
        __asm
        {
            int 3;
        }

        return 0;
    }

    When you will do an F5 ( Start Debugging ) from Visual Studio, then the debugger will break at the point where the instruction int 3; is. Visual Studio gives the message like below-

    breakpoint 

    You might be thinking that How it is going to help you, you can always do it through setting up a break point on any statement using F9. Below is the scenario where the given code is very helpful.

    You might want to attach windbg to the executable and keep it running until a certain point and then break right there. If you have the debug exe which have the code like above, it will break in windbg right there.

     pic2

    This was a small but cool tip, so just wanted to share.

    I am planning to put some more debugging with windbg stuff here.

    Nitin Dhawan

    Windows SDK – Microsoft

  • Expecting IGMPv3 packets to go out of the machine, but IGMPv2 packets are going out, What is the problem?

    Possible Scenario:  On Windows XP or Windows Server 2003 by default IGMPv3 is enabled. When you send a IGMP multicast packet after joining the multicast group using IP_ADD_SOURCE_MEMBERSHIP and setsockopt(), you see that IGMPv2 packet is going out of the machine, while you are expecting IGMPv3 to go out. What’s wrong?

     

    Then you check the registry key below to see if you are actually on IGMPv3 or not—

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

    IGMPVersion                DWORD            4

     

    Or as per the KB below in “Configure the registry” section.

    You Cannot Configure Windows XP or Windows Server 2003 to Use IGMP Version 1 or Version 2 Support

    If the value is 4 for IGMPVersion, then your machine is using IGMPv3, your code is correct because may be it is giving right result for some other customer or network. Now what is wrong?

    The reason is, if any machine or router in the network is using lower version of IGMP than v3, then the complete network falls back to that version. So, your machine/interface will start using lower version of the IGMP. This is by design. This is clearly demonstrated in ietf website.

    IGMP Mixed Version Proxying , see slides 11, 12 and 13.

     

    But I want to send only IGMPv3, no matter if network falls back to lower version if other machine/device is using lower version, What to do?

    No, there is no way to do that. This is by design and as per the RFC.

     

    Other scenario, my machine is configured for IGMPv3, but I am getting the problem as above. Now, if I disable and then enable the interface, I see some IGMPv3 packets going out, but later I get IGMPv2 only, Why?

    When interface get enables and machine is configured to use IGMPv3, it starts sending IGMPv3 packets, but as soon as an IGMPv2 query is received on the interface, it falls back to IGMPv2. Later, it’s all sending out IGMPv2 packets.

    Nitin Dhawan

    Windows SDK- Microsoft

  • Mapped Drive - Can't create Mapped Drive / Can't access Mapped Drive. What's happenning?

    Developing with mapped drives on Windows machines, you can often get the similar messages like subject of this article. What’s wrong?

    Even sometimes, you can see the mapped drive in explorer or using  “net use”, but still your application can’t use it. Why?

     

    The information has been documented on many KBs on http://support.microsoft.com like link below, but I am just trying to convey the message in different words.

    INFO: Services and Redirected Drives

     

    Reason:  The information can be found documented at many places, I just want to point on the documentation of the API which is used to create mapped drive programmatically, WNetAddConnection2 Function (Windows), see Remarks Section.

    Remarks

    On Windows Server 2003 and Windows XP, the WNet functions create and delete network drive letters in the MS-DOS device namespace associated with a logon session because MS-DOS devices are identified by AuthenticationID (a locally unique identifier, or LUID, associated with a logon session.) This can affect applications that call one of the WNet functions to create a network drive letter under one user logon, but query for existing network drive letters under a different user logon. An example of this situation could be when a user's second logon is created within a logon session, for example, by calling the CreateProcessAsUser function, and the second logon runs an application that calls the GetLogicalDrives function. The call to the GetLogicalDrives function does not return network drive letters created by WNet function calls under the first logon. Note that in the preceding example the first logon session still exists, and the example could apply to any logon session, including a Terminal Services session. For more information, see Defining an MS-DOS Device Name.

    So, if you create the mapped drive through explorer under user’s context and try to use it through a web application running under NETWORK SERVICE, the application code will fail to use mapped drive.

     

    You can test it non-programmatically as well. I used Windows Vista for this demo.

     

    1.       Launch a command prompt as logged on user. Type below command.   

    Net use   k:   \\machinename\share

                    If it is successful, the mapped drive will be created.

     

    2.       Launch a command prompt as “runas /user:someuser2 cmd.exe” by giving the password for “someuser2” . Type below command.

    Net use

                    You will see that the drive is not available, but in explorer windows you can see it.

     

    3.       Now from the command prompt launched in #2, run below command.

    Net use  k:  \\machinename2\share

    If it is successful, the mapped drive will be created.

     

    Two mapped drives with same drive letter, with different target, on same machine…..?

     

    4.       Now you have two mapped drive created on the same system with same drive letter but to two different locations. How do you test it?

    You can see the mapped drive created in #1 through explorer. Switch user to “someuser2” and see if there is another mapped drive created, which you created in #3.

     

    Observe the difference.  Mapped drives are restricted to per user.

     

    I think above information is good enough to explain that mapped drives are strictly restricted to user specific.

     

    Nitin Dhawan

    Windows SDK – Microsoft

  • Mapped drives can’t be created after Microsoft Security Update from code running under Network Service account

    Mapped drives can’t be created after Microsoft Security Update from code running under Network Service account

    MS09-012: Description of the security update for Windows Service Isolation: April 2009 ( KB 956572 )

     

    Possible scenario: You are using web application running under Network Service account and the code creates mapped drives using WNetAddConnection* APIs and fails stating ERROR_ALREADY_ASSIGNED error 85.

     

    With this update installed on the machine, you will not be able to create mapped drive from the Network Service account. This is intentionally blocked for Network Service account.

    Uninstalling the security update, Network Service account is able to create the mapped drive through WNetAddConnection* API successfully.

     

    Verify if this is the case and options to workaround--

    #1, If you have this issue, see if the update is installed on your machine. Check though Control Panel Installed Programs and updates or type “systeminfo” on command prompt.

    #2, To make sure this is the issue, see if you can uninstall the update. If after uninstalling the update, if your code in Network Service is able to create the mapped drive, then security update was causing it to fail.

    #3, Recommendation is, try using a different account to run the application which will make the application and security update to co-exist on the machine.

    #4, else If it is not at all possible then try below registry change to revert back the changes of update in this regard.

    Key-       “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager”

                                    ProtectionMode              DWORD                0

     

    Restart the machine to take it in effect.

     

    Thanks.

     

    Nitin Dhawan

    Windows SDK - Microsoft

  • File.Exists /_access / GetFileAttributes / FindFirstFile,FindNextFile / _stat behavior over SMB 2.0

    Problem Observed: When an application on client creates a file on a shared directory on server or application on server creates a file on shared directory on server, and file is created successfully but when the application on client try to check the existence of the recently created file by _access or other method, it reports that the file does not exists. This behavior is observed when SMB 2.0 is used.

    SMB 2.0 was introduced on Windows Vista and Windows Server 2008. The file does exists about after 10+ seconds.

     

    Is it a bug with SMB 2.0 ?

    No it is not a bug.

     

    Is this by design with SMB 2.0?

    Yes, this is a design change with SMB 2.0.

     

    What is really happening?

    This is because of the local caching included on the client side with SMB 2.0. When the SMB 2.0 session has been created, the local cache will be available on the client side, which will be refreshed after every 10 seconds by default. Any further request to the file exists will be checked against this local cache rather than going to the server share. So, if a local cache is built on client, and on server share a new file is created, local cache has not been invalidated and not in sync with server share, any further request for checking the new file existence will fail. This is root cause, but by design.

    If the local cache is updated and in sync with server share, request will be successful.

     

    How do I control the local cache lifetime?

    You can create registry keys below to control the cache lifetime.

    Under  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters:

     

    FileInfoCacheLifetime

    FileNotFoundCacheLifetime

    DirectoryCacheLifetime

     

    They are all REG_DWORD type in seconds.

     

    Programmatic workaround?

    Register for directory or file change notifications using Win32 API.

    Use FindFirstChangeNotification Function (Windows) API to register for changes.

    Sample can be found here Obtaining Directory Change Notifications (Windows)

     

     

     

    Open for any questions here. Thanks.

     

    Nitin Dhawan

    Windows SDK - Microsoft

More Posts Next page »

This Blog

Syndication


© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker