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

📄 pcmcia.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    }

    //
    // Delete some values so we no longer mistake it for a valid active key.
    //
    RegDeleteValue(hActiveKey, DEVLOAD_CLIENTINFO_VALNAME);
    RegDeleteValue(hActiveKey, DEVLOAD_HANDLE_VALNAME);
    RegDeleteValue(hActiveKey, DEVLOAD_DEVNAME_VALNAME);
    RegDeleteValue(hActiveKey, DEVLOAD_DEVKEY_VALNAME);
    RegDeleteValue(hActiveKey, DEVLOAD_PNPID_VALNAME);
    RegDeleteValue(hActiveKey, DEVLOAD_SOCKET_VALNAME);
    RegCloseKey(hActiveKey);
}   // DeleteActiveValues


//
// Function to DeregisterDevice a device and remove its active key and announce
// the device's removal to the system.
//
BOOL
I_DeactivateDevice(
    HANDLE hDevice,
    LPTSTR ActivePath
    )
{
    HKEY hActiveKey;
    DWORD status;
    DWORD ValLen;
    DWORD ValType;
    TCHAR DevName[DEVNAME_LEN];
    BOOL bAnnounce;

    bAnnounce = FALSE;

    //
    // Open its active key in the registry
    //
    status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                ActivePath,
                0,
                0,
                &hActiveKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
           (TEXT("DEVICE!I_DeactivateDevice: RegOpenKeyEx(%s) returned %d\r\n"),
           ActivePath, status));
    } else {
        // We're going to need the name
        ValLen = sizeof(DevName);
        status = RegQueryValueEx(
                     hActiveKey,
                     DEVLOAD_DEVNAME_VALNAME,
                     NULL,
                     &ValType,
                     (PUCHAR)DevName,
                     &ValLen);
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
               (TEXT("DEVICE!I_DeactivateDevice: RegQueryValueEx(DevName) returned %d\r\n"),
               status));
            RegCloseKey(hActiveKey);
        } else {
            bAnnounce = TRUE;
        }

        CallTapiDeviceChange(hActiveKey, DevName, TRUE); // bDelete == TRUE
        RegCloseKey(hActiveKey);
    }
#ifndef TARGET_NT
    DeregisterDevice((HANDLE)hDevice);
#else
    {    extern BOOL FS_DeregisterDevice(HANDLE);
        FS_DeregisterDevice((HANDLE)hDevice);
    }
#endif // TARGET_NT
    status = RegDeleteKey(HKEY_LOCAL_MACHINE, ActivePath);
    if (status) {
        DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,(TEXT("DEVICE!I_DeactivateDevice: RegDeleteKey failed %d\n"), status));
        DeleteActiveValues(ActivePath);
    }

    //
    // Announce to the world after the key has been deleted
    //
    if (bAnnounce) {
        StartDeviceNotify(DevName, FALSE);
    }
    return TRUE;
}


//
// Returns TRUE if there is a card inserted in the specified socket
//
BOOL
IsCardInserted(
    CARD_SOCKET_HANDLE hSock
    )
{
    STATUS status;
    CARD_STATUS CardStatus;

    CardStatus.hSocket = hSock;
    status = pfnGetStatus(&CardStatus);
    if (status == CERR_SUCCESS) {
        if (CardStatus.fCardState & EVENT_MASK_CARD_DETECT) {
            return TRUE;
        }
    } else {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!IsCardInserted: CardGetStatus returned %d\r\n"), status));
    }
    return FALSE;
}   // IsCardInserted


//
// This is the PCMCIA callback function specified in CardRegisterClient.
// PCMCIA indicates card insertions and removals by calling this function.
//
STATUS PcmciaCallBack(
    CARD_EVENT EventCode,
    CARD_SOCKET_HANDLE hSock,
    PCARD_EVENT_PARMS pParms
    )
{
#define MAX_UNLOAD_DEVICES 32

    DWORD DevHandle;
    DWORD n;
    TCHAR ActivePath[REG_PATH_LEN];

    switch (EventCode) {
    case CE_CARD_INSERTION:
        //
        // If no key exists in the active list for this socket, then this
        // insertion notice is for a newly inserted card (i.e. it is not an
        // artificial insertion notice)
        //
        if (IsCardInserted(hSock) == TRUE) {
            DevHandle = FindActiveBySocket(hSock, ActivePath);
            if (DevHandle == 0) {
                //
                // Look in the registry for a matching PNP id or device type
                // and load the corresponding DLL.
                //
                FindPCCardDriver(
                    hSock,
                    (LPTSTR)pParms->Parm1 /* PNP ID string */);
            }
#ifdef INSTRUM_DEV
			instrum_cardInserted = TRUE;
			SetEvent(instrum_insertEvent);
#endif
        }
        break;

    case CE_CARD_REMOVAL:
        //
        // If this is not an artificial removal notice, then DeregisterDevice the
        // associated device and remove its instance from the active list.
        //
        if (IsCardInserted(hSock) == FALSE) {
#ifdef INSTRUM_DEV
			instrum_cardInserted = FALSE;
#endif
        for (n = 0; n < MAX_UNLOAD_DEVICES; n++) {
            DevHandle = FindActiveBySocket(hSock, ActivePath);
            if (DevHandle) {
                I_DeactivateDevice((HANDLE)DevHandle, ActivePath);
            } else {
                break;  // no more devices
            }
          }
        }
        break;

    case CE_PM_RESUME:
        //
        // This event occurs after the forced removals due to power off and
        // after the subsequent inserts have occured.  The filesystem needs an
        // indication at this time to know that it's safe to do pc card I/O
        //
#ifndef TARGET_NT
        DEBUGMSG(ZONE_PCMCIA,
            (TEXT("DEVICE!PcmciaCallBack: Calling FileSystemPowerFunction(FSNOTIFY_DEVICES_ON\r\n")));
        WaitForFSDs();
        FileSystemPowerFunction(FSNOTIFY_DEVICES_ON);
        NotifyFSDs();
#endif // TARGET_NT
        break;
    }

    return CERR_SUCCESS;
}   // PcmciaCallBack



//
// Called at end of device.exe initialization.
//
VOID
InitPCMCIA(VOID)
{
    CARD_REGISTER_PARMS Parms;

#ifdef TARGET_NT
	// Check the wceemuld NT device driver.
	if (!check_wceemuld()) {
		v_hPcmciaDll = 0;
		return;
	}
#endif

    if (!(v_hPcmciaDll = LoadDriver(TEXT("PCMCIA.DLL")))) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
            (TEXT("DEVICE!InitPCMCIA: Failed to load PCMCIA.DLL\r\n")));
    	return;
   	}

    pfnRegisterClient = (REGISTERCLIENT) GetProcAddress(v_hPcmciaDll, TEXT("CardRegisterClient"));
    pfnGetFirstTuple = (GETFIRSTTUPLE) GetProcAddress(v_hPcmciaDll, TEXT("CardGetFirstTuple"));
    pfnGetNextTuple = (GETNEXTTUPLE) GetProcAddress(v_hPcmciaDll, TEXT("CardGetNextTuple"));
    pfnGetTupleData = (GETTUPLEDATA) GetProcAddress(v_hPcmciaDll, TEXT("CardGetTupleData"));
    pfnGetStatus = (GETSTATUS) GetProcAddress(v_hPcmciaDll, TEXT("CardGetStatus"));
    pfnSystemPower = (SYSTEMPOWER) GetProcAddress(v_hPcmciaDll, TEXT("CardSystemPower"));

    if ((v_hPcmciaDll == NULL) || 
        (pfnRegisterClient == NULL) || 
        (pfnGetFirstTuple == NULL) ||
        (pfnGetNextTuple == NULL) ||
        (pfnGetTupleData == NULL) ||
        (pfnGetStatus == NULL)) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
            (TEXT("DEVICE!InitPCMCIA: Failed to load PCMCIA.DLL\r\n")));
        FreeLibrary(v_hPcmciaDll);
        v_hPcmciaDll = NULL;
        return;
    }

#ifdef INSTRUM_DEV
	start_instrum_thread(v_hPcmciaDll);
#endif // INSTRUM_DEV

    //
    // Register callback function with PCMCIA driver
    //
    Parms.fEventMask = EVENT_MASK_CARD_DETECT|EVENT_MASK_POWER_MGMT;
    Parms.fAttributes = CLIENT_ATTR_IO_DRIVER | CLIENT_ATTR_NOTIFY_SHARED |
                        CLIENT_ATTR_NOTIFY_EXCLUSIVE;
    v_hPcmcia = (CARD_CLIENT_HANDLE)pfnRegisterClient(PcmciaCallBack, &Parms);
    if (v_hPcmcia == 0) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
            (TEXT("DEVICE!InitPCMCIA: CardRegisterClient failed %d\r\n"), GetLastError()));
        return;
    }
}   // InitPCMCIA


void
InitTapiDeviceChange(
    HKEY hActiveKey
    )
{
#ifndef TARGET_NT
    TCHAR DevName[DEVNAME_LEN];
    DWORD ValType;
    DWORD ValLen;
    DWORD status;

    //
    // Get the device name out of its active key in the registry
    //
    ValLen = sizeof(DevName);
    status = RegQueryValueEx(
                hActiveKey,
                DEVLOAD_DEVNAME_VALNAME,
                NULL,
                &ValType,
                (PUCHAR)DevName,
                &ValLen);

    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
            (TEXT("DEVICE!InitTapiDeviceChange: RegQueryValueEx(DevName) returned %d\r\n"),
            status));
        return;
    }

    if (CallTapiDeviceChange(hActiveKey, DevName, FALSE /* bDelete == FALSE */)) {    
        //
        // Cause a WM_DEVICECHANGE message to be posted and CeEventHasOccurred to
        // be called while we have all the information available.
        //
        StartDeviceNotify(DevName, TRUE);
    }
#endif // TARGET_NT
}   // InitTapiDeviceChange


//
// Let TAPI know about the active devices.
// Called after the whole system has initialized.
//
void InitTAPIDevices(void)
{
#ifndef TARGET_NT
    DWORD RegEnum;
    DWORD status;
    DWORD ValLen;
    HKEY ActiveKey;
    HKEY ActiveDevKey;
    TCHAR DevNum[DEVNAME_LEN];
    TCHAR RegPath[REG_PATH_LEN];

    if (v_hTapiDLL) {
        return;
    }

	v_hTapiDLL = (HMODULE)LoadDriver(TEXT("TAPI.DLL"));
    if (v_hTapiDLL == NULL) {
        return;
    }

    //
    // Walk the active device list and call InitTapiDeviceChange(ADD) for
    // each one since there will be tapi devices loaded before TAPI.DLL gets
    // loaded.  Tapi will only get notified if there is a Tsp value in the
    // device key for the active device.
    //
    _tcscpy(RegPath, s_ActiveKey);
    status = RegOpenKeyEx(
                    HKEY_LOCAL_MACHINE,
                    RegPath,
                    0,
                    0,
                    &ActiveKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
            (TEXT("DEVICE!InitTAPIDevices: RegOpenKeyEx(%s) returned %d\r\n"),
            RegPath, status));
        return;
    }

    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!InitTAPIDevices: RegEnumKeyEx() returned %d\r\n"),
                status));
            RegCloseKey(ActiveKey);
            return;
        }

        status = RegOpenKeyEx(
                    ActiveKey,
                    DevNum,
                    0,
                    0,
                    &ActiveDevKey);
        if (status != ERROR_SUCCESS) {
            DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
                (TEXT("DEVICE!InitTAPIDevices: RegOpenKeyEx(%s) returned %d\r\n"),
                DevNum, status));
        } else {
            InitTapiDeviceChange(ActiveDevKey);
            RegCloseKey(ActiveDevKey);
        }

        RegEnum++;
    }   // while
#endif // TARGET_NT
}   // InitTAPIDevices

⌨️ 快捷键说明

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