// reloaddrv.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPWSTR    lpCmdLine,
                   int       nCmdShow)
{
    BOOL bLoad = TRUE;
    LPWSTR pszToken = wcstok(lpCmdLine, L" ");
    while (pszToken)
    {   // Process parameters
        if (wcsicmp(pszToken, L"-u")==0)
        {   // Reset load flag if only unload requested
            bLoad = FALSE;
            pszToken = wcstok(NULL, L" ");
            continue;
        }

        // See if the driver is loaded
        DEVMGR_DEVICE_INFORMATION devInfo = {0};
        LPWSTR pszDeviceKey = NULL;
        devInfo.dwSize = sizeof(devInfo);
        HANDLE hFind = FindFirstDevice(DeviceSearchByLegacyName, pszToken, &devInfo);
        if (INVALID_HANDLE_VALUE != hFind)
        {   // Clean up find handle
            FindClose(hFind);
            // Store driver registry key
            pszDeviceKey = wcsdup(devInfo.szDeviceKey);
            // Unload driver
            RETAILMSG(1, (L"Found driver \"%s\", unloading...", devInfo.szLegacyName));
            DeactivateDevice(devInfo.hDevice);
        }
        else
            RETAILMSG(1, (L"Driver \"%s\" not loaded.", pszToken));

        if (bLoad)
        {   // Load driver if requested
            if (NULL == pszDeviceKey)
            {   // Try to find driver key in registry
                WCHAR szPrefix[4] = {0};
                DWORD dwIndex = 0;
                wcsncpy(szPrefix, pszToken, 3);
                dwIndex = _wtol(&pszToken[3]);
                HKEY hKey;
                BOOL bFound = FALSE;
                if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Drivers\\BuiltIn", 0, NULL, &hKey))
                {   // Opened BuiltIn drivers key
                    DWORD i = 0;
                    WCHAR szDriverKey[MAX_PATH];
                    DWORD dwCount = _countof(szDriverKey);
                    while (ERROR_NO_MORE_ITEMS != RegEnumKeyEx(hKey, i++, szDriverKey, &dwCount, NULL, NULL, NULL, NULL))
                    {   // Enumerate all driver keys
                        HKEY hDriverKey;
                        if (ERROR_SUCCESS == RegOpenKeyEx(hKey, szDriverKey, 0, NULL, &hDriverKey))
                        {   // Check if the prefix matches the specified one
                            WCHAR szDriverPrefix[MAX_PATH] = {0};
                            dwCount = sizeof(szDriverPrefix);
                            RegQueryValueEx(hDriverKey, L"Prefix", NULL, NULL, (LPBYTE)szDriverPrefix, &dwCount);
                            if (0 == wcsicmp(szPrefix, szDriverPrefix))
                            {   // And check if the index matches the specified one
                                DWORD dwDriverIndex = 0;
                                dwCount = sizeof(dwDriverIndex);
                                RegQueryValueEx(hDriverKey, L"Index", NULL, NULL, (LPBYTE)&dwDriverIndex, &dwCount);
                                if (dwDriverIndex == dwIndex)
                                {   // We found our driver key!
                                    bFound = TRUE;
                                    RegCloseKey(hDriverKey);
                                    break;
                                }
                            }
                            RegCloseKey(hDriverKey);
                        }
                        dwCount = _countof(szDriverKey);
                    }
                    if (bFound)
                    {   // Copy driver key name into pszDeviceKey
                        pszDeviceKey = (LPWSTR)malloc(MAX_PATH * sizeof(WCHAR));
                        if (pszDeviceKey)
                            wsprintf(pszDeviceKey, L"Drivers\\BuiltIn\\%s", szDriverKey);
                    }
                    else
                        RETAILMSG(1, (L"Can't find device key for \"%s\"...", pszToken));
                    RegCloseKey(hKey);
                }
            }
            if (pszDeviceKey)
            {   // Reload driver
                RETAILMSG(1, (L"Reloading from \"%s\"...", pszDeviceKey));
                ActivateDeviceEx(pszDeviceKey, NULL, 0, NULL);
            }
        }
        // Clean up and get ready for next parameter
        if (pszDeviceKey)
            free(pszDeviceKey);
        bLoad = TRUE;
        pszToken = wcstok(NULL, L" ");
    }
    return 0;
}



