⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 device.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 4 页
字号:
                        // Until this problem gets fixed in the loader, we can just "predict"            // when this will happen and do an extra FreeLibrary on FSDMGR.DLL. -JTP            //if (fInitEx && pfsd->hFSDLibEx)            //    FreeLibrary(hFSDLib);   // perform an "extra" FreeLibrary            DEBUGMSG(ZONE_FSD,(TEXT("DEVICE!GetFSD found existing instance (%x)\n"), pfsd));            return pfsd;        }        pfsd = pfsd->next;    }    //    // Remember this newly loaded file system driver dll    //    pfsd = LocalAlloc(LPTR, sizeof(fsd_t));    if (pfsd) {        pfsd->hFSDLib = hFSDLib;        if (!fInitEx) {            pfsd->pfnFSDInit =                (pInitFn)GetProcAddress(pfsd->hFSDLib, L"FSD_Init");            pfsd->pfnFSDDeinit =                (pDeinitFn)GetProcAddress(pfsd->hFSDLib, L"FSD_Deinit");        }        //        // Link it into the global list        //        pfsd->next = g_lpFSDChain;        g_lpFSDChain = pfsd;    }    else {        FreeLibrary(hFSDLib);   // if we don't have enough memory, free the library        DEBUGMSG(TRUE,(TEXT("DEVICE!GetFSD freed 0x%08x (ran out of memory)\n"), hFSDLib));    }    DEBUGMSG(ZONE_FSD,(TEXT("DEVICE!GetFSD created new instance (%x)\n"), pfsd));    return pfsd;}#define DEVICE_NAME_SIZE 6  // i.e. "COM1:" (includes space for 0 terminator)void FormatDeviceName(LPWSTR lpszName, fsdev_t * lpdev){    memcpy(lpszName, lpdev->type, sizeof(lpdev->type));    lpszName[sizeof(lpdev->type)/sizeof(WCHAR)+0] = (WCHAR)(L'0' + lpdev->index);    lpszName[sizeof(lpdev->type)/sizeof(WCHAR)+1] = L':';    lpszName[sizeof(lpdev->type)/sizeof(WCHAR)+2] = 0;}//// Context structure FS_LoadFSD passes to LoadFSDThread//typedef struct _FSD_LOAD_CONTEXT {    HANDLE hDevice;    LPWSTR lpFSDName;} FSD_LOAD_CONTEXT, * PFSD_LOAD_CONTEXT;//// LoadFSDThread - Function to perform the actual work of FS_LoadFSD in case// FSD displays a dialog requiring a user response.//DWORDLoadFSDThread(    PFSD_LOAD_CONTEXT pContext    ){	fsdev_t *lpdev;    pfsd_t pfsd;    lpdev = (fsdev_t *)pContext->hDevice;    DEBUGMSG(ZONE_FSD,(TEXT("DEVICE!LoadFSDThread(0x%x, %s)\n"), lpdev, pContext->lpFSDName));    EnterCriticalSection(&g_devcs);    //    // Try to load the FSD DLL for this device now.    //    lpdev->pfsd = pfsd = GetFSD(pContext->lpFSDName, FALSE);    if (pfsd) {        WCHAR wsDev[DEVICE_NAME_SIZE];        FormatDeviceName(wsDev, lpdev);        // We're ready to call the FSD now, and we want to release device.exe's        // global critical section before doing so, but lest another driver using        // the same FSD try to unload in the meantime, we must pre-increment        // the FSD's ref count (cFSDDevices) beforehand, to prevent the FSD getting        // unloaded out from under us.        pfsd->cFSDDevices++;        LeaveCriticalSection(&g_devcs);        if (pfsd->pfnFSDInit)            lpdev->dwFSDData = pfsd->pfnFSDInit((DWORD)wsDev);        else if (pfsd->pfnFSDInitEx)            lpdev->dwFSDData = pfsd->pfnFSDInitEx(pfsd->hFSDLibEx, wsDev, NULL);        EnterCriticalSection(&g_devcs);        // dwFSDData will be zero if the mount failed, and it will be        // ODD if pfnFSDInit simply remounted an existing volume, so in both those        // cases, we must back off the increment we applied to the FSD's ref count above.        if (lpdev->dwFSDData == 0 || (lpdev->dwFSDData & 0x1))            pfsd->cFSDDevices--;    // either the mount failed or it was actually a remount                if (lpdev->dwFSDData == 0) {            DoFreeFSD(pfsd);            lpdev->pfsd = pfsd = NULL;        }    }    // Clear DEVFLAGS_FSD_NEEDTOWAIT before releasing g_devcs to avoid unnecessary context switching    lpdev->wFlags &= ~DEVFLAGS_FSD_NEEDTOWAIT;    LeaveCriticalSection(&g_devcs);    LocalFree(pContext->lpFSDName);    LocalFree(pContext);    DEBUGMSG(ZONE_FSD,(TEXT("DEVICE!LoadFSDThread: done\n")));    return 0;}////  @func   BOOL | LoadFSD | Load a file system driver//  @parm   HANDLE | hDevice | handle to registered device, from RegisterDevice//  @parm   LPCWSTR | lpFSDName | Name of file system driver DLL to load//  @rdesc  Returns TRUE for success, FALSE for failure//  @comm   LoadFSD is used by a device driver to load its associated file//                  system driver (e.g. ATADISK.DLL loads FATFS.DLL)//                  An example would be:<nl>//                      <tab>LoadFSD(h1, FSDName);<nl>//                      where h1 is the handle returned by RegisterDevice//                      and FSDName points to the name of the FSD DLL.//BOOL FS_LoadFSD(HANDLE hDevice, LPCWSTR lpFSDName){    return FS_LoadFSDEx(hDevice, lpFSDName, LOADFSD_ASYNCH);}////  @func   BOOL | LoadFSDEx | Load a file system driver synch or asynch//  @parm   HANDLE | hDevice | handle to registered device, from RegisterDevice//  @parm   LPCWSTR | lpFSDName | Name of file system driver DLL to load//  @parm	DWORD | dwFlag | indicates synchronous or asynchronous load of file system //  @rdesc  Returns TRUE for success, FALSE for failure//  @comm   LoadFSDEx is used by a device driver to load its associated file//                  system driver (e.g. ATADISK.DLL loads FATFS.DLL)//                  An example would be:<nl>//                      <tab>LoadFSDEx(h1, FSDName, Flag);<nl>//                      where h1 is the handle returned by RegisterDevice//                      and FSDName points to the name of the FSD DLL.//						and Flag is one of the following:<nl>//						<tab>LOADFSD_ASYNCH creates a thread to load the requested DLL<nl>//						<tab>LOADFSD_SYNCH waits for the requested DLL to load before continuing<nl>//BOOL FS_LoadFSDEx(HANDLE hDevice, LPCWSTR lpFSDName, DWORD dwFlag){    HANDLE hThd;    PFSD_LOAD_CONTEXT pContext;    fsdev_t *lpdev = (fsdev_t *)hDevice;    pContext = LocalAlloc(LPTR, sizeof(FSD_LOAD_CONTEXT));    if (pContext == NULL) {        return FALSE;    }    pContext->lpFSDName = LocalAlloc(LPTR,                                   (_tcslen(lpFSDName) + 1) * sizeof(TCHAR));    if (pContext->lpFSDName == NULL) {        LocalFree(pContext);        return FALSE;    }    wcscpy(pContext->lpFSDName, lpFSDName);    pContext->hDevice = hDevice;    lpdev->wFlags |= DEVFLAGS_FSD_NEEDTOWAIT;    switch(dwFlag)    	{    	case LOADFSD_SYNCH:    		{    		LoadFSDThread(pContext);			hThd = NULL;			return TRUE;			break;    		}    	case LOADFSD_ASYNCH:    	default:    		{		    hThd = CreateThread(NULL, 0,                     (LPTHREAD_START_ROUTINE)&LoadFSDThread,                     (LPVOID) pContext, 0, NULL);    		if (hThd != NULL)     			{        		CloseHandle(hThd);        		return TRUE;    			}    		break;    		}    	}    lpdev->wFlags &= ~DEVFLAGS_FSD_NEEDTOWAIT;    LocalFree(pContext->lpFSDName);    LocalFree(pContext);    return FALSE;}////  @func   BOOL | CeResyncFilesys | Cause a file system driver to remount a device because of media change.//  @parm   HANDLE | hDevice | handle to registered device from RegisterDevice//  @rdesc  Returns TRUE for success, FALSE for failure//  @comm   CeResyncFilesys is used by a device driver to indicate to its associated file//                  system driver that a new volume/media has been inserted. The handle can be retrieved from//                  the device's active key in the registry or from the p_hDevice field of the POST_INIT_BUF//                  structure passed to the post-initialization IOCTL.//                  //BOOL FS_CeResyncFilesys(HANDLE hDevice){    fsdev_t *lpdev;    pfsd_t pfsd;    WCHAR wsDev[DEVICE_NAME_SIZE];    BOOL bDeinit;    lpdev = (fsdev_t *)hDevice;    if (!IsValidDevice(lpdev)) {        DEBUGMSG(ZONE_ERROR,(L"DEVICE: CeResyncFilesys - invalid handle\n"));        return FALSE;   // Invalid device handle    }    pfsd = lpdev->pfsd;    if (pfsd == NULL) {        DEBUGMSG(ZONE_ERROR, (L"DEVICE: CeResyncFilesys - No associated FSD\n"));        return FALSE;   // No associated FSD    }    InterlockedIncrement(&lpdev->dwRefCnt);    bDeinit = FALSE;    if (pfsd->pfnFSDDeinit)        bDeinit = pfsd->pfnFSDDeinit(lpdev->dwFSDData);    else if (pfsd->pfnFSDDeinitEx)        bDeinit = pfsd->pfnFSDDeinitEx(lpdev->dwFSDData);    else{         DEBUGMSG(ZONE_ERROR, (L"DEVICE: CeResyncFilesys - No FSDDeinit\n"));        goto fcrf_fail;    }    FormatDeviceName(wsDev, lpdev);    if (pfsd->pfnFSDInit)        lpdev->dwFSDData = pfsd->pfnFSDInit((DWORD)wsDev);    else if (pfsd->pfnFSDInitEx)        lpdev->dwFSDData = pfsd->pfnFSDInitEx(pfsd->hFSDLibEx, wsDev, NULL);    else {        DEBUGMSG(ZONE_ERROR, (L"DEVICE: CeResyncFilesys - No FSDInit\n"));        goto fcrf_fail;    }    InterlockedDecrement(&lpdev->dwRefCnt);    return TRUE;fcrf_fail:    if (bDeinit)        lpdev->pfsd->cFSDDevices--;    InterlockedDecrement(&lpdev->dwRefCnt);    return FALSE;}void FS_PowerAllDevices(BOOL bOff) {	fsdev_t *lpdev;    //    // Power on the PCMCIA system before powering on devices    //    if (!bOff && pfnSystemPower)	    pfnSystemPower(bOff);    if (bOff) {        //        // Notify drivers of power off in reverse order from their LoadOrder        //        for (lpdev = (fsdev_t *)g_DevChain.Blink;             lpdev != (fsdev_t *)&g_DevChain;             lpdev = (fsdev_t *)lpdev->list.Blink) {			if (lpdev->PwrOn) {				if (lpdev->fnPowerdn) {					ENTER_INSTRUM {	                lpdev->fnPowerdn(lpdev->dwData);					} EXIT_INSTRUM_POWERDOWN;				}				lpdev->PwrOn = FALSE;			}		}	} else {        //        // Notify drivers of power on according to their LoadOrder        //        for (lpdev = (fsdev_t *)g_DevChain.Flink;             lpdev != (fsdev_t *)&g_DevChain;             lpdev = (fsdev_t *)lpdev->list.Flink) {			if (!lpdev->PwrOn) {				if (lpdev->fnPowerup) {					ENTER_INSTRUM {					lpdev->fnPowerup(lpdev->dwData);					} EXIT_INSTRUM_POWERUP;				}				lpdev->PwrOn = TRUE;			}		}	}    //    // Power off the PCMCIA system after powering off devices    //    if (bOff && pfnSystemPower)	    pfnSystemPower(bOff);}BOOL FS_GetDeviceByIndex(DWORD dwIndex, LPWIN32_FIND_DATA lpFindFileData) {	fsdev_t *lpdev;	BOOL bRet = FALSE;	ENTER_DEVICE_FUNCTION {		lpdev = (fsdev_t *)g_DevChain.Flink;		while (dwIndex && lpdev != (fsdev_t *)&g_DevChain) {			dwIndex--;			lpdev = (fsdev_t *)lpdev->list.Flink;		}		if (lpdev != (fsdev_t *)&g_DevChain) {			lpFindFileData->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;		    *(__int64 *)&lpFindFileData->ftCreationTime = 0;		    *(__int64 *)&lpFindFileData->ftLastAccessTime = 0;		    *(__int64 *)&lpFindFileData->ftLastWriteTime = 0;		    lpFindFileData->nFileSizeHigh = 0;		    lpFindFileData->nFileSizeLow = 0;		    lpFindFileData->dwOID = 0xffffffff;            FormatDeviceName(lpFindFileData->cFileName, lpdev);		    bRet = TRUE;		}	} EXIT_DEVICE_FUNCTION;	return bRet;}// assumes len == 5 and lpnew[4] == ':'HANDLE FS_CreateDeviceHandle(LPCWSTR lpNew, DWORD dwAccess, DWORD dwShareMode, HPROCESS hProc){	HANDLE hDev = INVALID_HANDLE_VALUE;    DWORD dwErrCode = ERROR_DEV_NOT_EXIST;	fsopendev_t *lpopendev;	fsdev_t *lpdev;    	ENTER_DEVICE_FUNCTION {        for (lpdev = (fsdev_t *)g_DevChain.Flink;             lpdev != (fsdev_t *)&g_DevChain;             lpdev = (fsdev_t *)lpdev->list.Flink) {	        if (!_wcsnicmp(lpNew,lpdev->type,                     sizeof(lpdev->type)/sizeof(WCHAR))) {				if ((DWORD)(lpNew[3]-L'0') == lpdev->index) {					if (!(lpopendev = LocalAlloc(LPTR,sizeof(fsopendev_t)))) {                        dwErrCode = ERROR_OUTOFMEMORY;						goto errret;					}					lpopendev->lpDev = lpdev;					lpopendev->lpdwDevRefCnt = &lpdev->dwRefCnt;                    LeaveCriticalSection(&g_devcs);					ENTER_INSTRUM {					lpopendev->dwOpenData = lpdev->fnOpen(lpdev->dwData,dwAccess,dwShareMode);					} EXIT_INSTRUM_OPEN;                    EnterCriticalSection(&g_devcs);					if ((!IsValidDevice(lpdev)) || (!lpopendev->dwOpenData)) {						LocalFree(lpopendev);                        // Don't set an error code, the driver should have done that.						goto errret;					}					lpopendev->hProc = hProc;					if (!(hDev = CreateAPIHandle(g_hDevFileApiHandle, lpopendev))) {						hDev = INVALID_HANDLE_VALUE;						dwErrCode = ERROR_OUTOFMEMORY;						LocalFree(lpopendev);						goto errret;					}                    // OK, we managed to create the handle                    dwErrCode = 0;					lpopendev->KHandle = hDev;					lpopendev->nextptr = g_lpOpenDevs;					g_lpOpenDevs = lpopendev;					break;				}			}		}errret:        if( dwErrCode ) {            SetLastError( dwErrCode );            // This debugmsg occurs too frequently on a system without a sound device (eg, CEPC)            DEBUGMSG(0, (TEXT("ERROR (device.c:FS_CreateDeviceHandle): %s, %d\r\n"), lpNew, dwErrCode));        }        	} EXIT_DEVICE_FUNCTION;	return hDev;}BOOL FS_DevCloseFileHandle(fsopendev_t *fsodev){	BOOL retval = FALSE;	fsopendev_t *fsTrav;    fsdev_t *lpdev;	ENTER_DEVICE_FUNCTION {		if (g_lpOpenDevs == fsodev)			g_lpOpenDevs = fsodev->nextptr;		else {            fsTrav = g_lpOpenDevs;            while (fsTrav != NULL && fsTrav->nextptr != fsodev) {                fsTrav = fsTrav->nextptr;            }            if (fsTrav != NULL) {                fsTrav->nextptr = fsodev->nextptr;            } else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -