wince6.0 获取SD ID

一般,我们获取SD ID是通过2种方法(实际上市一回事,只不过是形式上不同而已),一是CreateFile(L"DSK2:", ...); 再DeviceIoControl(hFile, IOCTL_DISK_GET_STORAGEID, NULL, 0, &storeID, MAX_PAT,&dwBytesRead, NULL); 这是一种比较常用的方法,很好用,得到的结果也很正确;第二种方法就是CreateFile(L"//StorageCard//VOL:", ...); 再DeviceIoControl(hFile, IOCTL_DISK_GET_STORAGEID, NULL, 0, &storeID, MAX_PAT,&dwBytesRead, NULL); 这也是我今天要说的方法,在wince5.0 中这个运行的很好,没有错误,但到了wince6.0中这个方法就不行了,CreateFile 可以得到句柄,但是DeviceIoControl 就不行了, Why? 是DeviceIoControl 有问题还是CreateFile 有问题?所以我们就不得去找微软的代码了,可微软文件系统的代码也没有全部给出来,DeviceIoControl 没有找到实际的执行流程,如果谁知道的话,麻烦告诉我一声!找CreateFile, 根据vcleaner  的提示,找到D:/WINCE600/PRIVATE/WINCEOS/COREOS/STORAGE/FSDMGR 目录下的volumeapi.cpp文件,找到 FSDMGR_CreateFileW 函数,我加了打印语句,CreateFile(L"//StorageCard//VOL:", ...);  的确是调用了这个函数,而CreateFile(L"DSK2:", ...);  没有调用这个函数,所以说应该是CreateFile出了问题!仔细分析这个函数,感觉创建句柄的时候的确有点问题,它创建的是一个文件类型句柄,不是一个Device 类型句柄,所以调用DeviceIoControl 会失败,以下是我修改后的代码:

 

EXTERN_C HANDLE FSDMGR_CreateFileW (MountedVolume_t* pVolume, HANDLE hProcess,

    const WCHAR* pPathName, DWORD Access, DWORD ShareMode,

    SECURITY_ATTRIBUTES* pSecurityAttributes, DWORD Create,

    DWORD FlagsAndAttributes, HANDLE hTemplate,

    PSECURITY_DESCRIPTOR pSecurityDescriptor, DWORD SecurityDescriptorSize)

{   

    HANDLE h = INVALID_HANDLE_VALUE;

 

    SECURITY_ATTRIBUTES SecurityAttributes;

 

    DEBUGCHK (!pSecurityAttributes);

    if (pSecurityDescriptor) {

        SecurityAttributes.nLength = sizeof (SECURITY_ATTRIBUTES);

        SecurityAttributes.lpSecurityDescriptor = pSecurityDescriptor;

        SecurityAttributes.bInheritHandle = FALSE;

        pSecurityAttributes = &SecurityAttributes;

    }

 

    LRESULT lResult = pVolume->EnterWithWait ();

 

    if (ERROR_SUCCESS == lResult) {

 

        // Get the topmost file system object associated with the volume.

        // If another filter is hooked between now and the time we call

        // create file, we'll still use this one. This file system object

        // will be referenced by the handle object.

        FileSystem_t* pFileSystem = pVolume->GetFileSystem ();

 

        DWORD Attributes = 0;

        if (OPEN_EXISTING != Create) {

            // If not trying to open an existing file, there is the

            // possibility that we will create a new one. In order to

            // properly generate notifications we need to detect whether or

            // not the file already exists using GetFileAttributes.

            Attributes = pFileSystem->GetFileAttributesW (pPathName);

        }               

       

        HANDLE hInt = pFileSystem->CreateFileW (hProcess, pPathName, Access,

                ShareMode, pSecurityAttributes, Create,

                FlagsAndAttributes, hTemplate);

       

        if (INVALID_HANDLE_VALUE != hInt) {

           

            // The file system succeeded creating/opening the file, so

            // allocate an FileSystemHandle_t object and associate it with the

            // MountedVolume_t object.

 

            // Indicate whether or not this is a console or psuedo-device

            // handle when creating the FileSystemHandle_t object. This will dictate

            // how notifications are performed on the handle.

            DWORD HandleType = FileSystemHandle_t::HDL_FILE; //Hugo

            //DWORD HandleType = FileSystemHandle_t::HDL_FILE | FileSystemHandle_t::HDL_PSUEDO;

            if (IsPsuedoDeviceName(pPathName))

            {

                HandleType |= FileSystemHandle_t::HDL_PSUEDO;

            }

            if (IsConsoleName (pPathName)) {

                HandleType |= FileSystemHandle_t::HDL_CONSOLE;

            }

            //RETAILMSG(1, (L"Hugo CreateFile:AllocFileHandle /r/n "));

            // Allocte a new handle object to track this item.

            h = pVolume->AllocFileHandle (reinterpret_cast<DWORD> (hInt),

                HandleType, pFileSystem, pPathName, Access);

       

            if (INVALID_HANDLE_VALUE != h) {

 

                // Perform notifications only when the handle is for a real file,

                // not a pseudo device handle or console handle. Devices and streams

                // shouldn't ever generate notifications.

                //if (FileSystemHandle_t::HDL_FILE == HandleType && hugo

                    //!IsPsuedoDeviceName (pPathName)) {

                    if (FileSystemHandle_t::HDL_FILE == HandleType ) {

                    // Successfully opened the file. Perform file notifications

                    // as required.

                    if (INVALID_FILE_ATTRIBUTES == Attributes) {

                        

                        // The file did not previously exist; notify that it has

                        // been added.

                        pVolume->NotifyPathChange (pPathName, FALSE, FILE_ACTION_ADDED);

                       

                    } else if ((CREATE_ALWAYS == Create) ||

                            (TRUNCATE_EXISTING == Create)) {

                           

                        // The file previously existed but is being re-created or

                        // truncated so notify that it has changed.

                        pVolume->NotifyPathChange (pPathName, FALSE, FILE_ACTION_MODIFIED);

                    }

                }

           

            } else {

           

                // Failed to allocate a handle object, so close the handle

                // that was returned by the file system.

                pFileSystem->CloseFile (reinterpret_cast<DWORD> (hInt));

            }

 

        } else if (pPathName && (wcsicmp (pPathName, L"//VOL:") == 0)) {

 

            // TODO: Privilege check for raw disk i/o. This requires more privilege than file i/o.

 

            // Clear error code set by the FSD when it failed to open VOL: on its own.

            SetLastError (ERROR_SUCCESS);

 

            // We failed to open the file, but if it is VOL: special case this

            // and allow direct partition access.

            h = pVolume->AllocFileHandle (reinterpret_cast<DWORD> (hInt),

                FileSystemHandle_t::HDL_PSUEDO, pFileSystem, pPathName, Access);

        }

       

        pVolume->Exit ();

 

    } else {

 

        SetLastError (lResult);

    }

   

    return h;

}

上面红色的是我添加的(注意我屏蔽的那行代码,开始我没加下面if 语句,就加了屏蔽的那行代码,系统跑不起来,有谁能告诉我why?),这样就OK,一切正常,sd id 也可以正确的读出来了!不知道vcleaner 跟微软确认的怎么样了,这是不是wince6 的bug?

 

你可能感兴趣的:(object,File,Security,WinCE,attributes,notifications)