📄 device.c
字号:
pfsd1 = pfsd1->next; } // we should never get here } }}void DoFreeDevice(fsdev_t *lpdev){ EnterCriticalSection(&g_devcs); if (lpdev->pfsd) DoFreeFSD(lpdev->pfsd); LeaveCriticalSection(&g_devcs); FreeLibrary(lpdev->hLib); LocalFree(lpdev);}void WaitForFSDs(){ fsdev_t *lpdev;restart: EnterCriticalSection(&g_devcs); for (lpdev = (fsdev_t *)g_DevChain.Flink; lpdev != (fsdev_t *)&g_DevChain; lpdev = (fsdev_t *)lpdev->list.Flink) { // If the FSD hasn't finished init'ing yet, we must wait... if (lpdev->wFlags & DEVFLAGS_FSD_NEEDTOWAIT) { DEBUGMSG(1/*ZONE_FSD*/,(TEXT("DEVICE!WaitForFSDs: waiting for FSD to finish init'ing device 0x%x first...\r\n"), lpdev)); LeaveCriticalSection(&g_devcs); Sleep(2000); goto restart; } } LeaveCriticalSection(&g_devcs);}void NotifyFSDs(){ int n; pfsd_t pfsd = g_lpFSDChain; pfsd_t pfsd1; EnterCriticalSection(&g_devcs); while (pfsd) { if (pfsd->pfnFSDDeinit && (n = pfsd->pfnFSDDeinit(0)) || pfsd->pfnFSDDeinitEx && (n = pfsd->pfnFSDDeinitEx(0))) { DEBUGMSG(ZONE_FSD,(TEXT("DEVICE!NotifyFSDs: FSD unmounted %d devices (out of %d)\n"), n, pfsd->cFSDDevices)); pfsd->cFSDDevices -= n; DEBUGMSG(pfsd->cFSDDevices < 0,(TEXT("DEVICE!NotifyFSDs: device count underflow! (%d)\n"), pfsd->cFSDDevices)); pfsd1 = pfsd; pfsd = pfsd->next; DoFreeFSD(pfsd1); } else { pfsd = pfsd->next; } } LeaveCriticalSection(&g_devcs);}//// IsValidDevice - function to check if passed in device handle is actually a// valid registered device.//// Return TRUE if it is a valid registered device, FALSE otherwise.//BOOLIsValidDevice( fsdev_t * lpdev ){ fsdev_t * lpTrav; for (lpTrav = (fsdev_t *)g_DevChain.Flink; lpTrav != (fsdev_t *)&g_DevChain; lpTrav = (fsdev_t *)(lpTrav->list.Flink)) { if (lpTrav == lpdev) { return TRUE; } } return FALSE;}//// Function to wait for the file system driver associated with the specified// device to finish initializing before deregistering the device.// (For instance when FATFS has a dialog up and the corresponding PC card is// removed, the PCMCIA callback thread would get blocked until the dialog// got dismissed. Now we spin up a thread so PCMCIA messages are not blocked.)//DWORDWaitForFSDInitThread( HANDLE hDevice ){ fsdev_t *lpdev = (fsdev_t *)hDevice; while (1) { EnterCriticalSection(&g_devcs); if (!(lpdev->wFlags & DEVFLAGS_FSD_NEEDTOWAIT)) { break; } LeaveCriticalSection(&g_devcs); DEBUGMSG(1/*ZONE_FSD*/, (TEXT("DEVICE!WaitForFSDInitThread: waiting for FSD to finish init'ing device 0x%x first...\n"), lpdev)); Sleep(2000); } LeaveCriticalSection(&g_devcs); FS_DeregisterDevice(hDevice); return 0;}// @func BOOL | DeregisterDevice | Deregister a registered device// @parm HANDLE | hDevice | handle to registered device, from RegisterDevice// @rdesc Returns TRUE for success, FALSE for failure// @comm DeregisterDevice can be used if a device is removed from the system or// is being shut down. An example would be:<nl>// <tab>DeregisterDevice(h1);<nl>// where h1 was returned from a call to RegisterDevice.// @xref <f RegisterDevice> <l Overview.WinCE Device Drivers>BOOL FS_DeregisterDevice(HANDLE hDevice){ fsdev_t *lpdev; fsopendev_t *lpopen; BOOL retval = FALSE; HANDLE hThd;restart: ENTER_DEVICE_FUNCTION { lpdev = (fsdev_t *)hDevice; if (!IsValidDevice(lpdev)) { goto errret; } // If an FSD hasn't finished init'ing yet, we should wait, // because if it does eventually successfully init, then it // will need to be de-init'ed as well. if (lpdev->wFlags & DEVFLAGS_FSD_NEEDTOWAIT) { DEBUGMSG(1/*ZONE_FSD*/,(TEXT("DEVICE!FS_DeregisterDevice: waiting for FSD to finish init'ing device 0x%x first...\n"), lpdev)); hThd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&WaitForFSDInitThread, (LPVOID) hDevice, 0, NULL); if (hThd != NULL) { CloseHandle(hThd); retval = TRUE; goto errret; } else { // // If we can't start a thread, then revert to polling. // LeaveCriticalSection(&g_devcs); Sleep(2000); goto restart; } } lpopen = g_lpOpenDevs; while (lpopen) { if (lpopen->lpDev == lpdev) lpopen->lpDev = 0; lpopen = lpopen->nextptr; } RemoveEntryList((PLIST_ENTRY)lpdev); if (lpdev->dwFSDData && lpdev->pfsd) { pfsd_t pfsd = lpdev->pfsd; if (pfsd->pfnFSDDeinit && pfsd->pfnFSDDeinit(lpdev->dwFSDData) || pfsd->pfnFSDDeinitEx && pfsd->pfnFSDDeinitEx(lpdev->dwFSDData) || pfsd->pfnFSDDeinit == NULL && pfsd->pfnFSDDeinitEx == NULL) { pfsd->cFSDDevices--; } } LeaveCriticalSection(&g_devcs); ENTER_INSTRUM { lpdev->fnDeinit(lpdev->dwData); } EXIT_INSTRUM_DEINIT; if ((!lpdev->dwRefCnt) && (!lpdev->pfsd)) { DoFreeDevice(lpdev); EnterCriticalSection(&g_devcs); } else { EnterCriticalSection(&g_devcs); InsertTailList(&g_DyingDevs, (PLIST_ENTRY)lpdev); DEBUGMSG(ZONE_DYING, (TEXT("DEVICE: About to Reset CleanDoneEvt.\r\n"))); ResetEvent(g_hCleanDoneEvt); SetEvent(g_hCleanEvt); } retval = TRUE;errret: ; } EXIT_DEVICE_FUNCTION; return retval;}//// @func HANDLE | ActivateDevice | Register a device and add it to the active list under HKEY_LOCAL_MACHINE\Drivers\Active.// @parm LPCWSTR | lpszDevKey | The driver's device key under HKEY_LOCAL_MACHINE\Drivers (for example "Drivers\PCMCIA\Modem")// @parm DWORD | dwClientInfo | Instance information to be stored in the device's active key.// @rdesc Returns a handle to a device, or 0 for failure. This handle should// only be passed to DeactivateDevice// @comm ActivateDevice will RegisterDevice the specified device and// create an active key in HKEY_LOCAL_MACHINE\Drivers\Active for the new device.// Also the device's creation is announced to the system via a// WM_DEVICECHANGE message and through the application notification system.//// An example would be:<nl>// <tab>hnd = ActivateDevice(lpszDevKey, dwClientInfo);<nl>// where hnd is a HANDLE that can be used for DeactivateDevice<nl>// lpszDevKey is the registry path in HKEY_LOCAL_MACHINE to the device// driver's device key which has values that specify the driver name and// device prefix.<nl>// dwClientInfo is a DWORD value that will be stored in the device's active// key.<nl>// @xref <f DeactivateDevice> <f RegisterDevice> <f DeregisterDevice> <l Overview.WinCE Device Drivers>//HANDLE FS_ActivateDevice( LPCWSTR lpszDevKey, DWORD dwClientInfo ){ CARD_SOCKET_HANDLE hSock; DEBUGMSG(1, (TEXT("DEVICE!ActivateDevice(%s, %d) entered\r\n"), lpszDevKey, dwClientInfo)); hSock.uSocket = 0xff; // Not a PCMCIA device. return StartOneDriver( (LPWSTR)lpszDevKey, NULL, // PnpID MAX_LOAD_ORDER, dwClientInfo, hSock);}//// Function to search through HLM\Drivers\Active for a matching device handle.// Return TRUE if the device is found. The device's active registry path will be// copied to the ActivePath parameter.// BOOLFindActiveByHandle( HANDLE hDevice, LPTSTR ActivePath ){ DWORD Handle; DWORD RegEnum; DWORD status; DWORD ValLen; DWORD ValType; LPTSTR RegPathPtr; HKEY DevKey; HKEY ActiveKey; TCHAR DevNum[DEVNAME_LEN]; _tcscpy(ActivePath, s_ActiveKey); status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, ActivePath, 0, 0, &ActiveKey); if (status != ERROR_SUCCESS) { DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR, (TEXT("DEVICE!FindActiveByHandle: RegOpenKeyEx(%s) returned %d\r\n"), ActivePath, status)); return FALSE; } RegEnum = 0; while (1) { ValLen = sizeof(DevNum)/sizeof(TCHAR); status = RegEnumKeyEx( ActiveKey, RegEnum, DevNum, &ValLen, NULL, NULL, NULL, NULL); if (status != ERROR_SUCCESS) { DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR, (TEXT("DEVICE!FindActiveByHandle: RegEnumKeyEx() returned %d\r\n"), status)); RegCloseKey(ActiveKey); return FALSE; } status = RegOpenKeyEx( ActiveKey, DevNum, 0, 0, &DevKey); if (status != ERROR_SUCCESS) { DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR, (TEXT("DEVICE!FindActiveByHandle: RegOpenKeyEx(%s) returned %d\r\n"), DevNum, status)); goto fad_next; } // // See if the handle value matches // ValLen = sizeof(Handle); status = RegQueryValueEx( DevKey, DEVLOAD_HANDLE_VALNAME, NULL, &ValType, (PUCHAR)&Handle, &ValLen); if (status != ERROR_SUCCESS) { DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR, (TEXT("DEVICE!FindActiveByHandle: RegQueryValueEx(%s\\Handle) returned %d\r\n"), DevNum, status)); // // We found an active device key with no handle value. // Handle = 0; goto fad_next; } if (Handle == (DWORD)hDevice) { // // Format the registry path // RegPathPtr = ActivePath + _tcslen(ActivePath); RegPathPtr[0] = (TCHAR)'\\'; RegPathPtr++; _tcscpy(RegPathPtr, DevNum); RegCloseKey(ActiveKey); RegCloseKey(DevKey); return TRUE; }fad_next: RegCloseKey(DevKey); RegEnum++; } // while} // FindActiveByHandle//// @func BOOL | DeactivateDevice | Deregister a registered device and remove// it from the active list.// @parm HANDLE | hDevice | handle to registered device, from ActivateDevice// @rdesc Returns TRUE for success, FALSE for failure// @comm DeactivateDevice will DeregisterDevice the specified device and// delete the device's active key from HKEY_LOCAL_MACHINE\Drivers\Active.// Also the device's removal is announced to the system via a// WM_DEVICECHANGE message and through the application notification system.// An example would be:<nl>// <tab>DeactivateDevice(h1);<nl>// where h1 was returned from a call to ActivateDevice.// @xref <f ActivateDevice> <f RegisterDevice> <f DeregisterDevice> <l Overview.WinCE Device Drivers>//BOOL FS_DeactivateDevice(HANDLE hDevice){ TCHAR ActivePath[REG_PATH_LEN]; if (FindActiveByHandle(hDevice, ActivePath)) { return I_DeactivateDevice(hDevice, ActivePath); } return FALSE;}//// Find a currently loaded FSD or load it//pfsd_t GetFSD(LPCWSTR lpFSDName, BOOL fInitEx){ pfsd_t pfsd; HMODULE hFSDLib; hFSDLib = LoadDriver(lpFSDName); if (hFSDLib == NULL) { DEBUGMSG(ZONE_FSD,(TEXT("DEVICE!GetFSD: LoadDriver(%s) failed %d\n"), lpFSDName, GetLastError())); return NULL; } // // If this FSD sports the new "FSD_MountDisk" interface, // then we want to load FSDMGR.DLL instead, and give FSDMGR.DLL // our handle to the FSD. // if (!fInitEx && GetProcAddress(hFSDLib, L"FSD_MountDisk")) { pfsd = GetFSD(L"FSDMGR.DLL", TRUE); if (pfsd) { pfsd->pfnFSDInitEx = (pInitExFn)GetProcAddress(pfsd->hFSDLib, L"FSDMGR_InitEx"); pfsd->pfnFSDDeinitEx = (pDeinitFn)GetProcAddress(pfsd->hFSDLib, L"FSDMGR_DeinitEx"); if (pfsd->pfnFSDInitEx && pfsd->pfnFSDDeinitEx) pfsd->hFSDLibEx = hFSDLib; else FreeLibrary(hFSDLib); return pfsd; } // If GetFSD(FSDMGR.DLL) failed for some reason, then the code below // will simply try to treat hFSDLib as an old-model FSD. Probably won't // work, unless someone really did write an FSD that supports both models. } // // If this file system driver is already loaded, then return a pointer to // its fsd struct. // pfsd = g_lpFSDChain; while (pfsd) { if (pfsd->hFSDLib == hFSDLib) { FreeLibrary(hFSDLib); // only keep one instance
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -