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

📄 device.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 4 页
字号:
/* File:    device.c * * Purpose: WinCE device manager * * Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. *///// This module contains these functions://  FS_RegisterDevice//  RegisterDeviceEx//  DoFreeFSD//  DoFreeDevice//  WaitForFSDs//  NotifyFSDs//  IsValidDevice//  FS_DeregisterDevice//  FS_ActivateDevice//  FindActiveByHandle//  FS_DeactivateDevice//  GetFSD//  FormatDeviceName//  LoadFSDThread//  FS_LoadFSD//  FS_LoadFSDEx//  FS_CeResyncFilesys//  FS_PowerAllDevices//  FS_GetDeviceByIndex//  FS_CreateDeviceHandle//  FS_DevCloseFileHandle//  FS_DevReadFile//  FS_DevWriteFile//  FS_DevSetFilePointer//  FS_DevDeviceIoControl//  FS_DevGetFileSize//  FS_DevGetFileInformation//  FS_DevFlushFileBuffers//  FS_DevGetFileTime//  FS_DevSetFileTime//  FS_DevSetEndOfFile//  FS_DevProcNotify//  FS_CloseAllDeviceHandles//  WinMain//#include <device.h>#include <devload.h>#include <devloadp.h>#include <cardserv.h>#include <console.h>#ifdef TARGET_NT#include <devemul.h>#include "proxy.h"#endif#ifdef INSTRUM_DEV#include <instrumd.h>#else#define ENTER_INSTRUM#define EXIT_INSTRUM_INIT#define EXIT_INSTRUM_DEINIT#define EXIT_INSTRUM_POWERDOWN#define EXIT_INSTRUM_POWERUP#define EXIT_INSTRUM_OPEN#define EXIT_INSTRUM_CLOSE#define EXIT_INSTRUM_READ#define EXIT_INSTRUM_WRITE#define EXIT_INSTRUM_SEEK#define EXIT_INSTRUM_IOCONTROL#endif // INSTRUM_DEV/* Device driver implementation *///      @doc    EXTERNAL OSDEVICE KERNEL//      @module device.c - device driver support | Device driver support functions.//      @topic WinCE Device Drivers | There are two types of device drivers.  The//      first type are specialized drivers.  These are keyboard, mouse/touch screen,//      and display drivers.  These drivers have specialized interfaces.  The other//      type of driver is the stream based device driver model.  Drivers following the//      stream based model will need to export several functions and be initialized//      before they can be used.  They can be accessed through standard file APIs such//      as OpenFile.  The driver dll must export a set of entrypoints of the form//      ttt_api, where ttt is the device id passed in lpszType to RegisterDevice, and//      api is a required or optional API.  The APIs required are: Init, Deinit, Open,//      Close, Read, Write, Seek, and IOCtl.//  Drivers which need interrupts can use kernel exported interrupt support //  routines. To understand the interrupt model and functions please look at//  <l Interrupt Support.Kernel Interrupt Support>//      @xref <f RegisterDevice> <f DeregisterDevice> //         <l Interrupt Support.Kernel Interrupt Support>//	notes on handling of unloading of dlls while threads are in those dlls://	1> routines which take the device critical section before calling into a dll do not need to//		adjust the reference count since the deregister call takes the critical section//	2> routines which do not take the device critical section do the following://		a> check if the device is still valid [ if (fsodev->lpDev) ]//		b> if so, increment the reference count, so dodec = 1, make call, decrement the reference count,//			set dodec = 0//		c> we assume we will not fault in the interlockedDecrement, since once we've succeeded in the//			increment, we know we won't fault on the decrement since nobody will be LocalFree'ing the device//		d> if we fault inside the actual function call, we'll do the decrement due to the dodec flag// 	3> We signal an event when we put someone on the DyingDevs list.  We can just poll from that point onwards//		since (1) it's a rare case and (2) it's cheaper than always doing a SetEvent if you decrement the//		reference count to 0.CRITICAL_SECTION g_devcs;LIST_ENTRY g_DevChain;LIST_ENTRY g_DyingDevs;fsopendev_t *g_lpOpenDevs;fsopendev_t *g_lpDyingOpens;HANDLE g_hDevApiHandle, g_hDevFileApiHandle, g_hCleanEvt, g_hCleanDoneEvt;fsd_t *g_lpFSDChain;//// Devload.c and pcmcia.c //typedef DWORD (*SYSTEMPOWER)(DWORD);extern SYSTEMPOWER pfnSystemPower;extern void DevloadInit(void);extern void DevloadPostInit(void);extern BOOL I_DeactivateDevice(HANDLE hDevice, LPWSTR ActivePath);extern HANDLE StartOneDriver(LPTSTR RegPath, LPTSTR PnpId,                  DWORD LoadOrder, DWORD ClientInfo, CARD_SOCKET_HANDLE hSock);#ifndef TARGET_NTconst PFNVOID FDevApiMethods[] = {	(PFNVOID)FS_DevProcNotify,	(PFNVOID)0,	(PFNVOID)FS_RegisterDevice,	(PFNVOID)FS_DeregisterDevice,	(PFNVOID)FS_CloseAllDeviceHandles,	(PFNVOID)FS_CreateDeviceHandle,	(PFNVOID)FS_LoadFSD,	(PFNVOID)FS_ActivateDevice,	(PFNVOID)FS_DeactivateDevice,	(PFNVOID)FS_LoadFSDEx,	(PFNVOID)FS_GetDeviceByIndex,	(PFNVOID)FS_CeResyncFilesys,};#define NUM_FDEV_APIS (sizeof(FDevApiMethods)/sizeof(FDevApiMethods[0]))const DWORD FDevApiSigs[NUM_FDEV_APIS] = {	FNSIG3(DW, DW, DW),                     // ProcNotify	FNSIG0(),	FNSIG4(PTR, DW, PTR, DW),       // RegisterDevice	FNSIG1(DW),                                     // DeregisterDevice	FNSIG0(),                                       // CloseAllDeviceHandles	FNSIG4(PTR, DW, DW, DW),            // CreateDeviceHandle	FNSIG2(PTR, PTR),            // LoadFSD	FNSIG2(PTR, DW),       // ActivateDevice	FNSIG1(DW),            // DeactivateDevice	FNSIG3(PTR, PTR, DW),	//LoadFSDEx	FNSIG2(DW, PTR),		// GetDeviceByIndex	FNSIG1(DW),	// CeResyncFilesys};const PFNVOID DevFileApiMethods[] = {    (PFNVOID)FS_DevCloseFileHandle,    (PFNVOID)0,    (PFNVOID)FS_DevReadFile,    (PFNVOID)FS_DevWriteFile,    (PFNVOID)FS_DevGetFileSize,    (PFNVOID)FS_DevSetFilePointer,    (PFNVOID)FS_DevGetFileInformationByHandle,	(PFNVOID)FS_DevFlushFileBuffers,	(PFNVOID)FS_DevGetFileTime,	(PFNVOID)FS_DevSetFileTime,	(PFNVOID)FS_DevSetEndOfFile,	(PFNVOID)FS_DevDeviceIoControl,};#define NUM_FAPIS (sizeof(DevFileApiMethods)/sizeof(DevFileApiMethods[0]))const DWORD DevFileApiSigs[NUM_FAPIS] = {    FNSIG1(DW),                                 // CloseFileHandle    FNSIG0(),    FNSIG5(DW,PTR,DW,PTR,PTR),  // ReadFile    FNSIG5(DW,PTR,DW,PTR,PTR),  // WriteFile    FNSIG2(DW,PTR),                             // GetFileSize    FNSIG4(DW,DW,PTR,DW),               // SetFilePointer    FNSIG2(DW,PTR),                             // GetFileInformationByHandle	FNSIG1(DW),                                     // FlushFileBuffers	FNSIG4(DW,PTR,PTR,PTR),         // GetFileTime	FNSIG4(DW,PTR,PTR,PTR),         // SetFileTime	FNSIG1(DW),                                     // SetEndOfFile,	FNSIG8(DW, DW, PTR, DW, PTR, DW, PTR, PTR), // DeviceIoControl};#endif // TARGET_NTPFNVOID FS_GetProcAddr(LPCWSTR type, LPCWSTR lpszName, HINSTANCE hInst) {	WCHAR fullname[32];	memcpy(fullname,type,3*sizeof(WCHAR));	fullname[3] = L'_';	wcscpy(&fullname[4],lpszName);	return (PFNVOID)GetProcAddress(hInst,fullname);}//      @func   HANDLE | RegisterDevice | Register a new device//  @parm       LPCWSTR | lpszType | device id (SER, PAR, AUD, etc) - must be 3 characters long//  @parm       DWORD | dwIndex | index between 0 and 9, ie: COM2 would be 2//  @parm       LPCWSTR | lpszLib | dll containing driver code//  @parm       DWORD | dwInfo | instance information//      @rdesc  Returns a handle to a device, or 0 for failure.  This handle should//                      only be passed to DeregisterDevice.//      @comm   For stream based devices, the drivers will be .dll or .drv files.//                      Each driver is initialized by//                      a call to the RegisterDevice API (performed by the server process).//                      The lpszLib parameter is what will be to open the device.  The//                      lpszType is a three character string which is used to identify the //                      function entry points in the DLL, so that multiple devices can exist//                      in one DLL.  The lpszLib is the name of the DLL which contains the//                      entry points.  Finally, dwInfo is passed in to the init routine.  So,//                      if there were two serial ports on a device, and comm.dll was the DLL//                      implementing the serial driver, it would be likely that there would be//                      the following init calls:<nl>//                      <tab>h1 = RegisterDevice(L"COM", 1, L"comm.dll",0x3f8);<nl>//                      <tab>h2 = RegisterDevice(L"COM", 2, L"comm.dll",0x378);<nl>//                      Most likely, the server process will read this information out of a//                      table or registry in order to initialize all devices at startup time.//      @xref <f DeregisterDevice> <l Overview.WinCE Device Drivers>//HANDLEFS_RegisterDevice(    LPCWSTR lpszType,    DWORD   dwIndex,    LPCWSTR lpszLib,    DWORD   dwInfo    ){    return RegisterDeviceEx(                lpszType,                dwIndex,                lpszLib,                dwInfo,                MAX_LOAD_ORDER+1                );}HANDLERegisterDeviceEx(    LPCWSTR lpszType,    DWORD dwIndex,    LPCWSTR lpszLib,    DWORD dwInfo,    DWORD dwLoadOrder    ){	HANDLE hDev = 0;	fsdev_t *lpdev = 0, *lpTrav;	DWORD retval = 0;	DEBUGMSG(ZONE_DYING, (TEXT("DEVICE: About to wait on CleanDoneEvt.\r\n")));	// Need to wait for any filesystem devices to finish getting deregistered 	// before we go ahead and register them again. This gets around problems	// with storage card naming. 	retval = WaitForSingleObject(g_hCleanDoneEvt, 5000);	DEBUGMSG(ZONE_DYING, (TEXT("DEVICE: Got CleanDoneEvt.\r\n")));		ASSERT(retval != WAIT_TIMEOUT);		retval = ERROR_SUCCESS;	// Initialize for success	if (dwIndex > 9) {		retval = ERROR_INVALID_PARAMETER;		goto errret;	}	if (!(lpdev = LocalAlloc(LPTR,sizeof(fsdev_t)))) {		retval = ERROR_OUTOFMEMORY;		goto errret;	}		__try {        memset(lpdev, 0, sizeof(fsdev_t));        memcpy(lpdev->type,lpszType,sizeof(lpdev->type));		lpdev->index = dwIndex;		if (!(lpdev->hLib = LoadDriver(lpszLib))) {			retval = ERROR_FILE_NOT_FOUND;		} else {			if (!(lpdev->fnInit = (pInitFn)FS_GetProcAddr(lpdev->type,L"Init",lpdev->hLib)) ||				!(lpdev->fnDeinit = (pDeinitFn)FS_GetProcAddr(lpdev->type,L"Deinit",lpdev->hLib)) ||				!(lpdev->fnOpen = (pOpenFn)FS_GetProcAddr(lpdev->type,L"Open",lpdev->hLib)) ||				!(lpdev->fnClose = (pCloseFn)FS_GetProcAddr(lpdev->type,L"Close",lpdev->hLib)) ||				!(lpdev->fnRead = (pReadFn)FS_GetProcAddr(lpdev->type,L"Read",lpdev->hLib)) ||				!(lpdev->fnWrite = (pWriteFn)FS_GetProcAddr(lpdev->type,L"Write",lpdev->hLib)) ||				!(lpdev->fnSeek = (pSeekFn)FS_GetProcAddr(lpdev->type,L"Seek",lpdev->hLib)) ||				!(lpdev->fnControl = (pControlFn)FS_GetProcAddr(lpdev->type,L"IOControl",lpdev->hLib))) {				retval = ERROR_INVALID_FUNCTION;			} else {				// Got all the required functions.  Now let's get the optional ones				lpdev->fnPowerup = (pPowerupFn)FS_GetProcAddr(lpdev->type,L"PowerUp",lpdev->hLib);				lpdev->fnPowerdn = (pPowerupFn)FS_GetProcAddr(lpdev->type,L"PowerDown",lpdev->hLib);			}		}	} __except (EXCEPTION_EXECUTE_HANDLER) {		retval = ERROR_INVALID_PARAMETER;	}	if (retval) {		goto errret;	}	// Now enter the critical section to look for it in the device list	EnterCriticalSection (&g_devcs);	__try {		//        // check for uniqueness        //        for (lpTrav = (fsdev_t *)g_DevChain.Flink;             lpTrav != (fsdev_t *)&g_DevChain;             lpTrav = (fsdev_t *)(lpTrav->list.Flink)) {            if (!memcmp(lpTrav->type,lpdev->type,sizeof(lpdev->type)) &&               (lpTrav->index == lpdev->index)) {                retval = ERROR_DEVICE_IN_USE;				break;            }		}	} __except (EXCEPTION_EXECUTE_HANDLER) {		retval = ERROR_INVALID_PARAMETER;	}	LeaveCriticalSection(&g_devcs);	if (retval) {		goto errret;	}		__try {		ENTER_INSTRUM {			lpdev->dwData = lpdev->fnInit(dwInfo);		} EXIT_INSTRUM_INIT;		if (!(lpdev->dwData)) {			retval = ERROR_OPEN_FAILED;		} else {			// Sucess			lpdev->PwrOn = TRUE;			lpdev->dwLoadOrder = dwLoadOrder;		}	} __except (EXCEPTION_EXECUTE_HANDLER) {		retval = ERROR_INVALID_PARAMETER;	}	if (retval) {		goto errret;	}	EnterCriticalSection(&g_devcs);	__try {        //        // Insert according to LoadOrder        //        for (lpTrav = (fsdev_t *)g_DevChain.Flink;             lpTrav != (fsdev_t *)&g_DevChain;             lpTrav = (fsdev_t *)(lpTrav->list.Flink)) {            if (lpTrav->dwLoadOrder >= dwLoadOrder) {                InsertHeadList((PLIST_ENTRY)lpTrav, (PLIST_ENTRY)lpdev);				break;            }        }		if (lpTrav == (fsdev_t *)&g_DevChain) {			// insert at the end			InsertTailList(&g_DevChain, (PLIST_ENTRY)lpdev);		}        hDev = (HANDLE)lpdev;	} __except (EXCEPTION_EXECUTE_HANDLER) {		retval = ERROR_INVALID_PARAMETER;	}	LeaveCriticalSection(&g_devcs);errret:	#ifdef DEBUG    if (ZONE_ACTIVE) {        if (hDev != NULL) {            DEBUGMSG(ZONE_ACTIVE, (TEXT("DEVICE: Name   Load Order\r\n")));            //            // Display the list of devices in ascending load order.            //			EnterCriticalSection(&g_devcs);            for (lpTrav = (fsdev_t *)g_DevChain.Flink;                 lpTrav != (fsdev_t *)&g_DevChain;                 lpTrav = (fsdev_t *)(lpTrav->list.Flink)) {                DEBUGMSG(ZONE_ACTIVE, (TEXT("DEVICE: %c%c%c%d:  %d\r\n"),                         lpTrav->type[0], lpTrav->type[1], lpTrav->type[2],                         lpTrav->index, lpTrav->dwLoadOrder));            }			LeaveCriticalSection(&g_devcs);        }    }#endif	// If we failed then let's clean up the module and data	if (retval) {		SetLastError (retval);		if (lpdev) {			if (lpdev->hLib) {				FreeLibrary(lpdev->hLib);			}			LocalFree (lpdev);		}	}	return hDev;}void DoFreeFSD(pfsd_t pfsd){    pfsd_t pfsd1;    if (pfsd->cFSDDevices <= 0) {        FreeLibrary(pfsd->hFSDLib);        if (pfsd == g_lpFSDChain) {            g_lpFSDChain = pfsd->next;            LocalFree(pfsd);            return;        } else {            pfsd1 = g_lpFSDChain;            while (pfsd1) {                if (pfsd1->next == pfsd) {                    pfsd1->next = pfsd->next;                    LocalFree(pfsd);                    return;                }

⌨️ 快捷键说明

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