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?

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章