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

📄 devcore.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                        DEBUGMSG(ZONE_WARNING, (_T("I_DeregisterDevice: exception in final deinit entry point\r\n")));
                    }
                }
                DeleteDevice(lpdev);
                bFreedOne = TRUE;
                break; 
                // break out of inner loop, because after letting go of critsec &
                // freeing lpdev, our loop traversal is not valid anymore. So start over
            }
        }
        if (bFreedOne == FALSE) {
            // Couldn't free anyone
            LeaveCriticalSection(&g_devcs);
            Sleep(5000);    // snooze, and try again...
        }
    }
}   // ProcessDyingDevs


//
// ProcessDyingOpens - called from the main thread as part of periodic clean up.
//
// Dying opens are orphaned device handles. A device open handle can be orphaned if
// CloseHandle is called by one thread while another thread using the same handle is
// blocked in a call to the device driver, for instance xxx_IoControl. When xxx_IoControl
// returns, DM_DevDeviceIoControl will access the open handle structure so it can't be freed
// yet; it is put on the g_lpDyingOpens list.
//
void ProcessDyingOpens(void)
{
    fsopendev_t *fsodev;
    fsopendev_t *fsodevprev;
    LPEXCEPTION_POINTERS pep;

    DEBUGMSG(ZONE_DYING, (L"Device:ProcessDyingOpens About to walk dying opens list\r\n"));
    EnterCriticalSection(&g_devcs);
    fsodevprev = fsodev = g_lpDyingOpens;
    while (fsodev) {
        if (fsodev->dwOpenRefCnt == 0) {
            fsdev_t *lpdev = fsodev->lpDev;
            if(lpdev != NULL && lpdev->fnPreClose != NULL) {
                LeaveCriticalSection(&g_devcs);
                __try {
                    lpdev->fnClose(fsodev->dwOpenData);
                }
                __except(pep = GetExceptionInformation(), ReportFault(pep,0), EXCEPTION_EXECUTE_HANDLER ) {
                    DEBUGMSG(ZONE_WARNING, (_T("ProcessDyingOpens: exception calling final close entry point\r\n")));
                }
                EnterCriticalSection(&g_devcs);
            }

            // Unlink and free unreferenced open
            if (fsodev == g_lpDyingOpens) {
                g_lpDyingOpens = fsodev->nextptr;
                LocalFree(fsodev);
                fsodev = fsodevprev = g_lpDyingOpens;
            } else {
                fsodevprev->nextptr = fsodev->nextptr;
                LocalFree(fsodev);
                fsodev = fsodevprev->nextptr;
            }
        } else {
            fsodevprev = fsodev;
            fsodev = fsodev->nextptr;
        }
    }
    LeaveCriticalSection(&g_devcs);
}   // ProcessDyingOpens


// Uses registry to call SignalStarted with the correct args.  Note that ideally
// device manager should NOT know this info is in the registry!
static void SignalStartedUsingReg()
{
#define MAX_APPSTART_KEYNAME 128
    HKEY   hKey;
    WCHAR  szName[MAX_APPSTART_KEYNAME];
    WCHAR  szVal[MAX_APPSTART_KEYNAME];
    LPWSTR lpszArg = NULL;
    DWORD  dwTemp, dwType, dwNameSize, dwValSize, i;

    if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("init"), 0, NULL, 0, 0,
                       NULL, &hKey, &dwTemp) != ERROR_SUCCESS) {
        DEBUGCHK(0);
        return;
    }

    dwNameSize = MAX_APPSTART_KEYNAME;
    dwValSize = MAX_APPSTART_KEYNAME * sizeof(WCHAR);
    i = 0;
    while (RegEnumValue(hKey, i, szName, &dwNameSize, 0, &dwType,
                        (LPBYTE)szVal, &dwValSize) == ERROR_SUCCESS) {
        if ((dwType == REG_SZ) && !wcsncmp(szName, TEXT("Launch"), 6) // 6 for "launch"
            && !wcscmp(szVal, TEXT("device.exe"))) {
            lpszArg = szName + 6; // 6 to go past "launch"
            break;
        }
        
        dwNameSize = MAX_APPSTART_KEYNAME;
        dwValSize = MAX_APPSTART_KEYNAME * sizeof(WCHAR);
        i++;
    }

    RegCloseKey(hKey);

    if (lpszArg) {
        SignalStarted(_wtol(lpszArg));
    } else {
        // device.exe is not in the registry!
        DEBUGMSG(1, (TEXT("Device manager must be listed in HKLM\\init!\r\n")));
        DEBUGCHK(0);
    }
}

// This routine initializes the Device Manager, Power Manager, and I/O Resource
// Manager APIs, launches device drivers, and processes device driver load/unload.
int WINAPI 
StartDeviceManager(HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR lpCmdLine, int nCmShow)
{

    HINSTANCE hCeddkDll;
    HANDLE hEvent;

    if (IsAPIReady(SH_DEVMGR_APIS)) {
        return 0;
    }
    
    DEBUGREGISTER(NULL);
    DEBUGMSG(ZONE_BOOTSEQ, (TEXT("DEVICE: Starting boot phase 1\n")));

    // PHASE 1
    g_BootPhase = 1;
    InitOOMSettings();
    InitializeListHead(&g_DevChain);
    InitializeListHead(&g_ActivatingDevs);
    InitializeListHead(&g_DyingDevs);
    InitializeListHead(&g_CandidateDevs);
    g_hCleanEvt = CreateEvent(NULL, FALSE, FALSE, NULL);
    g_hDevApiHandle = CreateAPISet("WFLD", NUM_FDEV_APIS, FDevApiMethods, FDevApiSigs);
    g_hDevFileApiHandle = CreateAPISet("W32D", NUM_FAPIS, DevFileApiMethods, DevFileApiSigs);
    RegisterAPISet(g_hDevFileApiHandle, HT_FILE | REGISTER_APISET_TYPE);
    InitializePnPNotifications();
    InitializeCriticalSection(&g_devcs);
    ResourceInitModule();
    ResourceInitFromRegistry(TEXT("Drivers\\Resources"));
    SetPowerOffHandler((FARPROC) DevMgrPowerOffHandler);
    RegisterAPISet(g_hDevApiHandle, SH_DEVMGR_APIS);
    InitDeviceFilesystems();

    // Indicate that the device manager is up and running
    hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("SYSTEM/DevMgrApiSetReady"));
    DEBUGCHK(hEvent != NULL);
    if (hEvent != NULL) {
        SetEvent(hEvent);
        CloseHandle(hEvent);
    }

    // Calibrate stall counter that is used for StallExecution
    hCeddkDll = LoadLibrary (TEXT("ceddk.dll"));
    if (NULL != hCeddkDll) {
        pCalibrateStallFn fnCalibrateStall = (pCalibrateStallFn)GetProcAddress(hCeddkDll, TEXT("CalibrateStallCounter"));
        if (!fnCalibrateStall) {
            DEBUGMSG(ZONE_BOOTSEQ,  (L"GetProcAddress failed on ceddk.dll\r\n"));
            FreeLibrary(hCeddkDll);       
        }
        else {
            fnCalibrateStall();
        }
    }

    // Call the power manager initialization entry point
    PM_Init();
    PM_SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);

    // See if we are going to have two boot phases
    hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _T("SYSTEM/BootPhase1"));
    if (hEvent != NULL) {
        // Load phase 1 drivers from the boot registry
        DevloadInit();

        // Signal boot phase 1 complete
        SetEvent(hEvent);
        CloseHandle(hEvent);

        // Wait for phase 2 of the boot to begin
        hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("SYSTEM/BootPhase2"));
        DEBUGCHK(hEvent);
        if (hEvent) {
            DEBUGMSG(ZONE_BOOTSEQ, (TEXT("DEVICE: Started, waiting for boot phase 2\r\n")));
            WaitForSingleObject(hEvent, INFINITE);
            CloseHandle(hEvent);
        }

        // Load any new drivers from the persistent registry.  Since the 
        // registry may have changed, update the power state for any devices
        // that need it.
        DEBUGMSG(ZONE_BOOTSEQ, (TEXT("DEVICE: Second-phase driver load\r\n")));
        g_BootPhase = 2;
        PM_SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
        InitDevices(NULL);
        
        DEBUGMSG(ZONE_BOOTSEQ, (TEXT("DEVICE: Startup sequence complete\r\n")));
        SignalStartedUsingReg(); // SignalStarted call with the right args
    
    } else {
        DEBUGMSG(ZONE_BOOTSEQ, (TEXT("DEVICE: No boot registry - skipping to boot phase 2\n")));
        g_BootPhase = 2;
        DevloadInit();
        SignalStarted(_wtol(lpCmdLine));
    }

    // Boot phase 3 isn't any different from phase 2; just marks that we got here.
    DEBUGMSG(ZONE_BOOTSEQ,
             (TEXT("DEVICE: Finished loading primary drivers - entering boot phase 3\n")));
    g_BootPhase = 3;
    
    CELOG_DeviceFinished ();
    
    while (1) {
        WaitForSingleObject(g_hCleanEvt, INFINITE);

        // check for auto-deregister devs first as they may end up queuing 
        // themselves on the dying devs list
        ProcessAutoDeregisterDevs();
        ProcessDyingDevs();
        ProcessDyingOpens();
    }
    
    return 1;    // should not ever be reached
}

// DLL entry point.
BOOL WINAPI
DllMain(
         HINSTANCE hDllHandle, 
         DWORD  dwReason, 
         LPVOID lpreserved
         ) 
{
    BOOL bRc = TRUE;
    
    UNREFERENCED_PARAMETER(hDllHandle);
    UNREFERENCED_PARAMETER(lpreserved);
    
    switch (dwReason) {
    case DLL_PROCESS_ATTACH: 
        {
            DEBUGREGISTER(hDllHandle);
            DEBUGMSG(ZONE_INIT,(_T("*** DLL_PROCESS_ATTACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
                GetCurrentProcess(), GetCurrentProcessId()));
            // is device manager already running?
            if(IsAPIReady(SH_DEVMGR_APIS)) {
                // yes -- we only allow one instance, so fail this entry point
                bRc = FALSE;
            } else {
                DisableThreadLibraryCalls((HMODULE) hDllHandle);
            }
        } 
        break;
        
    case DLL_PROCESS_DETACH: 
        {
            DEBUGMSG(ZONE_INIT,(_T("*** DLL_PROCESS_DETACH - Current Process: 0x%x, ID: 0x%x ***\r\n"),
                GetCurrentProcess(), GetCurrentProcessId()));
        } 
        break;
        
    default:
        break;
    }
    
    return bRc;
}

⌨️ 快捷键说明

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