Export (0) Print
Expand All

8 Appendix C: IDMNotify::ObjectsChanged

void CClientClass::ObjectsChanged( DWORD dwByteCount, BYTE *pByte)
{
    DWORD   dwNotifSize     = 0;
    DWORD   dwCopySize      = 0;
    BYTE    *pPos           = pByte;
    BYTE    *pNotifStart    = NULL;

    DMNOTIFY_INFO_TYPE  Type;
    LDMACTION           Action;


    while (pPos - pByte < (long)dwByteCount)
    {
        pNotifStart = pPos;

        // Get the notification size.
        memcpy( &dwNotifSize, pPos, sizeof(DWORD) );
        pPos = pPos + sizeof(DWORD);

        // Get the notification type.
        memcpy( &Type, pPos, sizeof(DMNOTIFY_INFO_TYPE) );
        pPos = pPos + sizeof(DMNOTIFY_INFO_TYPE);

        // Get the notification action.
        memcpy( &Action, pPos, sizeof(LDMACTION) );
        pPos = pPos + sizeof(LDMACTION);

        // dwCopySize is the number of bytes left to copy out 
        // of the byte stream for this notification.
        dwCopySize = dwNotifSize 
            - ( sizeof(DWORD) 
                + sizeof(DMNOTIFY_INFO_TYPE) 
                    + sizeof(LDMACTION) );
        
        // Switch on the type of this notification.
        switch (Type) {

        case DMNOTIFY_DISK_INFO:
            
        // We need to treat IVolumeClient server and IVolumeClient3 
        // server differently. IVolumeClient server uses DISK_INFO,
        // IVolumeClient3 uses DISK_INFO_EX. The code below will load 
        // DISK_INFO into a DISK_INFO_EX structure for the case where 
        // the server is Windows 2000 and the client is Windows XP or
        // Windows 2003.

            DISK_INFO_EX DiskInfoEx;

            memset(&DiskInfoEx,0,sizeof(DISK_INFO_EX));

            if ( nIVolumeClientVersion == 3 )
            {
                dwCopySize = offsetof(DISK_INFO_EX,name);
                
                memcpy(&DiskInfoEx,pPos,offsetof(DISK_INFO_EX,name));
                pPos = pPos + dwCopySize;
            }
            else    // nIVolumeClientVersion == 1
            {

                //
                // Copy the first part of disk info structure.
                // 

                DISK_INFO DiskInfo;

                memset(&DiskInfo,0,sizeof(DISK_INFO));
                
                //
                // On a 64-bit client, 4 bytes of padding are added
                // after cchDgName, so we cannot set dwCopySize to 
                // offsetof(DISK_INFO,name) - the byte stream passed
                // from the 32-bit server does not have these 4 bytes
                // of padding.
                //
                // However, if the client is 32 bit and the server is
                // 64 bit, the code below sets pPos to point to the 
                // padding. 
                //
                //  dwCopySize = offsetof(DISK_INFO,cchDgName) 
                //                 + sizeof(DiskInfo.cchDgName);
                //  memcpy( &DiskInfo, pPos, dwCopySize );
                //  pPos = pPos + dwCopySize;     
                // pPos may now be incorrect.
                //
                // We have this problem below in the DMNOTIFY_FS_INFO
                // case.
                //
                // The workaround is to setup globals that store the
                // server and client architecture. For the client, call
                // the Win32 API GetSystemInfo().
                //
                // For the server, use the Disk Management interfaces
                // to look for an ESP partition on any of the client 
                // disks. If one is found, assume a 64-bit 
                // architecture. For this code, assume 
                // g_ClientArchitecture and g_ServerArchitecture have 
                // been setup.
                //

                if ( g_ClientArchitecture == g_ServerArchitecture ) {
                    dwCopySize = offsetof(DISK_INFO, name)
                    memcpy( &DiskInfo, pPos, dwCopySize );
                    pPos = pPos + dwCopySize;      
                }
                else if ( g_ClientArchitecture == 32 bit ) {
                    dwCopySize = offsetof(DISK_INFO,name);
                    memcpy( &DiskInfo, pPos, dwCopySize );
                    pPos = pPos + dwCopySize;      
                }
                else {      // ( g_ServerArchitecture == 32 bit )
                    dwCopySize = offsetof(DISK_INFO,cchDgName) 
                        + sizeof(DiskInfo.cchDgName);
                    memcpy( &DiskInfo, pPos, dwCopySize );
                    pPos = pPos + dwCopySize;       
                }
                
                //
                // Copy from DISK_INFO to DISK_INFO_EX
                //

                CopyToDiskInfoEx( &DiskInfo, &DiskInfoEx );
            }

            // Copy disk name.
            wchar_t *name;
            name = new wchar_t[DiskInfoEx.cchName * sizeof(wchar_t)];
             			if (name)
                				memcpy( name, 
                        pPos, 
                        sizeof(wchar_t) * DiskInfoEx.cchName );
            pPos = pPos + (sizeof(wchar_t) * DiskInfoEx.cchName);

            // Copy disk vendor.
            wchar_t *vendor;
            vendor = new wchar_t[DiskInfoEx.cchVendor 
                * sizeof(wchar_t)];
               		if (vendor)
                    	memcpy( vendor, 
                         pPos, 
                         sizeof(wchar_t) * DiskInfoEx.cchVendor );
            pPos = pPos + (sizeof(wchar_t) * DiskInfoEx.cchVendor);

            // Copy disk group id.
            BYTE *dgid;
            dgid = new BYTE[DiskInfoEx.cchDgid * sizeof(BYTE)];
          		if (dgid)
            			 memcpy( dgid, 
                    pPos, 
                    sizeof(BYTE) * DiskInfoEx.cchDgid );
            pPos = pPos + (sizeof(BYTE) * DiskInfoEx.cchDgid);

            // Copy disk adapter.
            wchar_t *adapterName;
            adapterName = new wchar_t[DiskInfoEx.cchAdapterName 
                            * sizeof(wchar_t)];
           if (adapterName)
                memcpy( adapterName, 
                    pPos, 
                    sizeof(wchar_t) * DiskInfoEx.cchAdapterName );
             pPos = pPos 
                 + (sizeof(wchar_t) * DiskInfoEx.cchAdapterName);

            // Copy disk group name.
            wchar_t *dgName;
            dgName = new wchar_t[DiskInfoEx.cchDgName 
                                   * sizeof(wchar_t)];
          		if (dgName)
   			          memcpy( dgName, 
                    pPos, 
                    sizeof(wchar_t) * DiskInfoEx.cchDgName );
            pPos = pPos + (sizeof(wchar_t) * DiskInfoEx.cchDgName);

            // Copy device instance id.
            wchar_t *devInstId;

            if ( nIVolumeClientVersion == 3 )
            {            
                // Copy device instance id.
                if (DiskInfoEx.cchDevInstId)
                {
                    devInstId = new wchar_t[DiskInfoEx.cchDevInstId * 
                        sizeof(wchar_t)];
                    if (devInstId)
                        memcpy( devInstId, pPos, sizeof(wchar_t) * 
                            DiskInfoEx.cchDevInstId );
                    pPos = pPos + (sizeof(wchar_t) * 
                        DiskInfoEx.cchDevInstId);
                }
                else
                    devInstId = NULL;
            }
            else        // nIVolumeClientVersion == 1
                devInstId = NULL;

            //
            // Assign the rest of the DISK_INFO_EX members.
            //
            DiskInfoEx.name = name;
            DiskInfoEx.vendor = vendor;
            DiskInfoEx.dgid = dgid;
            DiskInfoEx.adapterName = adapterName;
            DiskInfoEx.dgName = dgName;
            DiskInfoEx.devInstId = devInstId;

            break;

        case DMNOTIFY_VOLUME_INFO:

            VOLUME_INFO VolumeInfo;

             memset( &VolumeInfo, 0, sizeof(VOLUME_INFO) );

             // Copy in volume info.

            memcpy( &VolumeInfo, pPos, dwCopySize );
            pPos = pPos + dwCopySize;

            break;

        case DMNOTIFY_REGION_INFO:

            REGION_INFO_EX RegInfoEx;

            memset( &RegInfoEx, 0, sizeof(REGION_INFO_EX) );

            // We need to treat IVolumeClient server and IVolumeClient3
            // server differently. IVolumeClient server uses 
            // REGION_INFO instead of REGION_INFO_EX. The code below
            // will load REGION_INFO into a REGION_INFO_EX structure 
            // for the case where the server is Windows 2000 and the
            // client is Windows XP or Windows 2003

            if ( nIVolumeClientVersion==3 )
            {
                memcpy( &RegInfoEx, 
                        pPos, 
                        offsetof(REGION_INFO_EX,name) );
                pPos += offsetof(REGION_INFO_EX,name);

                // Copy name.
                wchar_t *name;
                name = new wchar_t[RegInfoEx.cchName 
                    * sizeof(wchar_t)];
             if (name)
             				   memcpy( name, 
                        pPos, 
                        sizeof(wchar_t) * RegInfoEx.cchName );
                pPos = pPos + (sizeof(wchar_t) * RegInfoEx.cchName);

                RegInfoEx.name = name;
            }
            else    // m_sIVolumeClientVersion == 1
            {
                REGION_INFO RegInfo;

                memset( &RegInfo, 0, sizeof(REGION_INFO) );

                memcpy( &RegInfo, pPos, dwCopySize );
                pPos = pPos + dwCopySize;

                CopyToRegionInfoEx( &RegInfo, &RegInfoEx );
            }
            break;

        case DMNOTIFY_TASK_INFO:

            TASK_INFO TaskInfo;

            memset( &TaskInfo, 0, sizeof(TASK_INFO) );

            // Copy in task info.

            memcpy( &TaskInfo, pPos, dwCopySize );
            pPos = pPos + dwCopySize;

            break;

        case DMNOTIFY_DL_INFO:

            DRIVE_LETTER_INFO DLInfo;

            memset( &DLInfo, 0, sizeof(DRIVE_LETTER_INFO) );

            // Copy in drive letter info.

            memcpy( &DLInfo, pPos, dwCopySize );
            pPos = pPos + dwCopySize;

            break;

        case DMNOTIFY_FS_INFO:

            FILE_SYSTEM_INFO FsInfo;

            memset( &FsInfo, 0, sizeof(FILE_SYSTEM_INFO) );
            
            //
            // We have this problem here as above in the 
          	// DMNOTIFY_DISK_INFO case.
            //
            // On a 64-bit client, 4 bytes of padding are added after 
            // cchLabel, so we cannot set dwCopySize to 
            // offsetof(FILE_SYSTEM, label) - the byte stream passed 
            // from the 32-bit server does not have these 4 bytes of 
            // padding.
            //
            // However, if the client is 32 bit and the server is 64
            // bit, the code below sets pPos to point to the padding. 
            //
            //  dwCopySize = offsetof(FILE_SYSTEM_INFO, cchLabel) 
            //                    + sizeof(FsInfo.cchLabel);
            //  memcpy( &FsInfo, pPos, dwCopySize );
            //  pPos = pPos + dwCopySize;  
            // pPos may now be incorrect.
            //

            // Copy file system info.

            if ( g_ClientArchitecture == g_ServerArchitecture ) {
                dwCopySize = offsetof(FILE_SYSTEM_INFO, label)
                memcpy( &DiskInfo, pPos, dwCopySize );
                pPos = pPos + dwCopySize;      
            }
            else if ( g_ClientArchitecture == 32 bit ) {
                dwCopySize = offsetof(FILE_SYSTEM_INFO,label);
                memcpy( &DiskInfo, pPos, dwCopySize );
                pPos = pPos + dwCopySize;       
            }
            else {      // ( g_ServerArchitecture == 32 bit )
                dwCopySize = offsetof(FILE_SYSTEM_INFO,cchLabel) 
                    + sizeof(FsInfo.cchLabel);
                memcpy( &DiskInfo, pPos, dwCopySize );
                pPos = pPos + dwCopySize;       
            }            

            // Copy the label.
            wchar_t *label;
            label = new wchar_t[FsInfo.cchLabel * sizeof(wchar_t)];
          if (label)
             			memcpy( label, 
                    pPos, 
                    sizeof(wchar_t) * FsInfo.cchLabel );
            pPos = pPos + (sizeof(wchar_t) * FsInfo.cchLabel);
            FsInfo.label = label;

            break;

        case DMNOTIFY_SYSTEM_INFO:
            
            DWORD SysInfo;
            
            memset( &SysInfo, 0, sizeof(DWORD) );

            // Copy in system info.

            memcpy( &SysInfo, pPos, dwCopySize );
            pPos = pPos + dwCopySize;

            break;

        } // switch

        pPos = pNotifStart + dwNotifSize;
    } // while

}



 
Show:
© 2014 Microsoft