/*++ Copyright (c) Microsoft Corporation. All rights reserved. Module Name: stub.c Abstract: Dynamic loading of routines that are implemented differently on Win9x and NT. Author: Jim Schmidt (jimschm) 29-Apr-1997 Revision History: jimschm 26-Oct-1998 Added cfgmgr32, crypt32, mscat and wintrust APIs lonnym 01-Apr-2000 Added VerifyVersionInfo and VerSetConditionMask --*/ #include "precomp.h" // // Stub & emulation prototypes -- implemented below // GETFILEATTRIBUTESEXA_PROTOTYPE EmulatedGetFileAttributesExA; // // Function ptr declarations. When adding, prefix the function ptr with // Dyn_ to indicate a dynamically loaded version of an API. // GETFILEATTRIBUTESEXA_PROC Dyn_GetFileAttributesExA; GETSYSTEMWINDOWSDIRECTORYA_PROC Dyn_GetSystemWindowsDirectoryA; VERIFYVERSIONINFOA_PROC Dyn_VerifyVersionInfoA; VERSETCONDITIONMASK_PROC Dyn_VerSetConditionMask; // // these functions are a little more involved, since we don't want to // pull in SFC until we have to (delay-load) // SFCONNECTTOSERVER_PROC Dyn_SfcConnectToServer = FirstLoad_SfcConnectToServer; SFCCLOSE_PROC Dyn_SfcClose = FirstLoad_SfcClose; SFCFILEEXCEPTION_PROC Dyn_SfcFileException = FirstLoad_SfcFileException; SFCISFILEPROTECTED_PROC Dyn_SfcIsFileProtected = FirstLoad_SfcIsFileProtected; #ifdef ANSI_SETUPAPI CM_QUERY_RESOURCE_CONFLICT_LIST Dyn_CM_Query_Resource_Conflict_List; CM_FREE_RESOURCE_CONFLICT_HANDLE Dyn_CM_Free_Resource_Conflict_Handle; CM_GET_RESOURCE_CONFLICT_COUNT Dyn_CM_Get_Resource_Conflict_Count; CM_GET_RESOURCE_CONFLICT_DETAILSA Dyn_CM_Get_Resource_Conflict_DetailsA; CM_GET_CLASS_REGISTRY_PROPERTYA Dyn_CM_Get_Class_Registry_PropertyA; CM_SET_CLASS_REGISTRY_PROPERTYA Dyn_CM_Set_Class_Registry_PropertyA; CM_GET_DEVICE_INTERFACE_ALIAS_EXA Dyn_CM_Get_Device_Interface_Alias_ExA; CM_GET_DEVICE_INTERFACE_LIST_EXA Dyn_CM_Get_Device_Interface_List_ExA; CM_GET_DEVICE_INTERFACE_LIST_SIZE_EXA Dyn_CM_Get_Device_Interface_List_Size_ExA; CM_GET_LOG_CONF_PRIORITY_EX Dyn_CM_Get_Log_Conf_Priority_Ex; CM_QUERY_AND_REMOVE_SUBTREE_EXA Dyn_CM_Query_And_Remove_SubTree_ExA; CM_REGISTER_DEVICE_INTERFACE_EXA Dyn_CM_Register_Device_Interface_ExA; CM_SET_DEVNODE_PROBLEM_EX Dyn_CM_Set_DevNode_Problem_Ex; CM_UNREGISTER_DEVICE_INTERFACE_EXA Dyn_CM_Unregister_Device_Interface_ExA; CRYPTCATADMINACQUIRECONTEXT Dyn_CryptCATAdminAcquireContext; CRYPTCATADMINRELEASECONTEXT Dyn_CryptCATAdminReleaseContext; CRYPTCATADMINRELEASECATALOGCONTEXT Dyn_CryptCATAdminReleaseCatalogContext; CRYPTCATADMINADDCATALOG Dyn_CryptCATAdminAddCatalog; CRYPTCATCATALOGINFOFROMCONTEXT Dyn_CryptCATCatalogInfoFromContext; CRYPTCATADMINCALCHASHFROMFILEHANDLE Dyn_CryptCATAdminCalcHashFromFileHandle; CRYPTCATADMINENUMCATALOGFROMHASH Dyn_CryptCATAdminEnumCatalogFromHash; CRYPTCATADMINREMOVECATALOG Dyn_CryptCATAdminRemoveCatalog; CRYPTCATADMINRESOLVECATALOGPATH Dyn_CryptCATAdminResolveCatalogPath; CERTFREECERTIFICATECONTEXT CertFreeCertificateContext; WINVERIFYTRUST WinVerifyTrust; #endif VOID InitializeStubFnPtrs ( VOID ) /*++ Routine Description: This routine tries to load the function ptr of OS-provided APIs, and if they aren't available, stub versions are used instead. We do this for APIs that are unimplemented on a platform that setupapi will run on. Arguments: none Return Value: none --*/ { // // no dynamic loading should be done here for WinXP etc // it's only done for ANSI version of setupapi.dll // who's sole purpose is for setup of WinXP // from Win9x (ie, used in context of winnt32.exe) // #ifdef ANSI_SETUPAPI // // Kernel32 API's - try loading from the OS dll, and if the API // doesn't exist, use an emulation version // (FARPROC) Dyn_GetFileAttributesExA = ObtainFnPtr ( "kernel32.dll", "GetFileAttributesExA", (FARPROC) EmulatedGetFileAttributesExA ); (FARPROC) Dyn_GetSystemWindowsDirectoryA = ObtainFnPtr ( "kernel32.dll", "GetSystemWindowsDirectoryA", (FARPROC) GetWindowsDirectoryA ); // // use Win9x config manager APIs if they exist, otherwise return ERROR_CALL_NOT_IMPLEMENTED // (FARPROC) Dyn_CM_Get_Class_Registry_PropertyA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Class_Registry_PropertyA", (FARPROC) Stub_CM_Get_Class_Registry_PropertyA ); (FARPROC) Dyn_CM_Set_Class_Registry_PropertyA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Set_Class_Registry_PropertyA", (FARPROC) Stub_CM_Set_Class_Registry_PropertyA ); (FARPROC) Dyn_CM_Get_Device_Interface_Alias_ExA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Device_Interface_Alias_ExA", (FARPROC) Stub_CM_Get_Device_Interface_Alias_ExA ); (FARPROC) Dyn_CM_Get_Device_Interface_List_ExA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Device_Interface_List_ExA", (FARPROC) Stub_CM_Get_Device_Interface_List_ExA ); (FARPROC) Dyn_CM_Get_Device_Interface_List_Size_ExA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Device_Interface_List_Size_ExA", (FARPROC) Stub_CM_Get_Device_Interface_List_Size_ExA ); (FARPROC) Dyn_CM_Get_Log_Conf_Priority_Ex = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Log_Conf_Priority_Ex", (FARPROC) Stub_CM_Get_Log_Conf_Priority_Ex ); (FARPROC) Dyn_CM_Query_And_Remove_SubTree_ExA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Query_And_Remove_SubTree_ExA", (FARPROC) Stub_CM_Query_And_Remove_SubTree_ExA ); (FARPROC) Dyn_CM_Register_Device_Interface_ExA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Register_Device_Interface_ExA", (FARPROC) Stub_CM_Register_Device_Interface_ExA ); (FARPROC) Dyn_CM_Set_DevNode_Problem_Ex = ObtainFnPtr ( "cfgmgr32.dll", "CM_Set_DevNode_Problem_Ex", (FARPROC) Stub_CM_Set_DevNode_Problem_Ex ); (FARPROC) Dyn_CM_Unregister_Device_Interface_ExA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Unregister_Device_Interface_ExA", (FARPROC) Stub_CM_Unregister_Device_Interface_ExA ); (FARPROC)Dyn_CM_Query_Resource_Conflict_List = ObtainFnPtr ( "cfgmgr32.dll", "CM_Query_Resource_Conflict_List", (FARPROC) Stub_CM_Query_Resource_Conflict_List ); (FARPROC)Dyn_CM_Free_Resource_Conflict_Handle = ObtainFnPtr ( "cfgmgr32.dll", "CM_Free_Resource_Conflict_Handle", (FARPROC) Stub_CM_Free_Resource_Conflict_Handle ); (FARPROC)Dyn_CM_Get_Resource_Conflict_Count = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Resource_Conflict_Count", (FARPROC) Stub_CM_Get_Resource_Conflict_Count ); (FARPROC)Dyn_CM_Get_Resource_Conflict_DetailsA = ObtainFnPtr ( "cfgmgr32.dll", "CM_Get_Resource_Conflict_DetailsA", (FARPROC) Stub_CM_Get_Resource_Conflict_DetailsA ); // // use Win9x crypto APIs if they exist, otherwise fail with ERROR_CALL_NOT_IMPLEMENTED // (FARPROC) Dyn_CryptCATAdminAcquireContext = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminAcquireContext", (FARPROC) Stub_CryptCATAdminAcquireContext ); (FARPROC) Dyn_CryptCATAdminReleaseContext = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminReleaseContext", (FARPROC) Stub_CryptCATAdminReleaseContext ); (FARPROC) Dyn_CryptCATAdminReleaseCatalogContext = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminReleaseCatalogContext", (FARPROC) Stub_CryptCATAdminReleaseCatalogContext ); (FARPROC) Dyn_CryptCATAdminAddCatalog = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminAddCatalog", (FARPROC) Stub_CryptCATAdminAddCatalog ); (FARPROC) Dyn_CryptCATCatalogInfoFromContext = ObtainFnPtr ( "wintrust.dll", "CryptCATCatalogInfoFromContext", (FARPROC) Stub_CryptCATCatalogInfoFromContext ); (FARPROC) Dyn_CryptCATAdminCalcHashFromFileHandle = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminCalcHashFromFileHandle", (FARPROC) Stub_CryptCATAdminCalcHashFromFileHandle ); (FARPROC) Dyn_CryptCATAdminEnumCatalogFromHash = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminEnumCatalogFromHash", (FARPROC) Stub_CryptCATAdminEnumCatalogFromHash ); (FARPROC) Dyn_CryptCATAdminRemoveCatalog = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminRemoveCatalog", (FARPROC) Stub_CryptCATAdminRemoveCatalog ); (FARPROC) Dyn_CryptCATAdminResolveCatalogPath = ObtainFnPtr ( "wintrust.dll", "CryptCATAdminResolveCatalogPath", (FARPROC) Stub_CryptCATAdminResolveCatalogPath ); (FARPROC) Dyn_CertFreeCertificateContext = ObtainFnPtr ( "crypt32.dll", "CertFreeCertificateContext", (FARPROC) Stub_CertFreeCertificateContext ); // // use Win9x WinVerifyTrust if it exists, otherwise return ERROR_SUCCESS // (FARPROC) Dyn_WinVerifyTrust = ObtainFnPtr ( "wintrust.dll", "WinVerifyTrust", (FARPROC) Stub_WinVerifyTrust ); // // Use VerifyVersionInfo and VerSetConditionMask APIs, // if available, otherwise fail with ERROR_CALL_NOT_IMPLEMENTED. // (FARPROC) Dyn_VerifyVersionInfoA = ObtainFnPtr( "kernel32.dll", "VerifyVersionInfoA", (FARPROC) Stub_VerifyVersionInfoA ); (FARPROC) Dyn_VerSetConditionMask = ObtainFnPtr( "ntdll.dll", "VerSetConditionMask", (FARPROC) Stub_VerSetConditionMask ); // // ***Add other dynamic loading here*** // #endif } BOOL EmulatedGetFileAttributesExA ( IN PCSTR FileName, IN GET_FILEEX_INFO_LEVELS InfoLevelId, OUT LPVOID FileInformation ) /*++ Routine Description: Implements an emulation of the NT-specific function GetFileAttributesEx. Basic exception handling is implemented, but parameters are not otherwise validated. Arguments: FileName - Specifies file to get attributes for InfoLevelId - Must be GetFileExInfoStandard FileInformation - Must be a valid pointer to WIN32_FILE_ATTRIBUTE_DATA struct Return Value: TRUE for success, FALSE for failure. GetLastError provided error code. --*/ { // // GetFileAttributesEx does not exist on Win95, and ANSI version of setupapi.dll // is required for Win9x to NT 5 upgrade // HANDLE FileEnum; WIN32_FIND_DATAA fd; PCSTR p,pChar; TCHAR CurChar; WIN32_FILE_ATTRIBUTE_DATA *FileAttribData = (WIN32_FILE_ATTRIBUTE_DATA *) FileInformation; __try { // // We only support GetFileExInfoStandard // if (InfoLevelId != GetFileExInfoStandard) { SetLastError (ERROR_INVALID_PARAMETER); return FALSE; } // // Locate file title // note that this is an ANSI implementation of pSetupGetFileTitle // p = pChar = FileName; while(CurChar = *pChar) { pChar = CharNextA(pChar); if((CurChar == '\\') || (CurChar == '/') || (CurChar == ':')) { p = pChar; } } ZeroMemory (FileAttribData, sizeof (WIN32_FILE_ATTRIBUTE_DATA)); FileEnum = FindFirstFileA (FileName, &fd); // // Prohibit caller-supplied pattern // if (FileEnum!=INVALID_HANDLE_VALUE && lstrcmpiA (p, fd.cFileName)) { FindClose (FileEnum); FileEnum = INVALID_HANDLE_VALUE; SetLastError (ERROR_INVALID_PARAMETER); } // // If exact match found, fill in the attributes // if (FileEnum) { FileAttribData->dwFileAttributes = fd.dwFileAttributes; FileAttribData->nFileSizeHigh = fd.nFileSizeHigh; FileAttribData->nFileSizeLow = fd.nFileSizeLow; CopyMemory (&FileAttribData->ftCreationTime, &fd.ftCreationTime, sizeof (FILETIME)); CopyMemory (&FileAttribData->ftLastAccessTime, &fd.ftLastAccessTime, sizeof (FILETIME)); CopyMemory (&FileAttribData->ftLastWriteTime, &fd.ftLastWriteTime, sizeof (FILETIME)); FindClose (FileEnum); } return FileEnum != INVALID_HANDLE_VALUE; } __except (TRUE) { // // If bogus FileInformation pointer is passed, an exception is thrown. // SetLastError (ERROR_INVALID_PARAMETER); return FALSE; } } // // DLL array structures // #define MAX_DLL_ARRAY 16 typedef struct { PCSTR DllName; HINSTANCE DllInst; } DLLTABLE, *PDLLTABLE; static INT g_ArraySize = 0; static DLLTABLE g_DllArray[MAX_DLL_ARRAY]; // // Attempt to get library out of System32 directory first // HMODULE DelayLoadLibrary( IN LPCSTR LibName ) /*++ internal Routine Description: Given an ANSI library name, prepend system32 directory and load it (ie, enforce our own search path) Don't assume anything is initialized Arguments: LibName - name passed to us by pDelayLoadHook Result: HMODULE from LoadLibrary, or NULL for default processing --*/ { CHAR path[MAX_PATH]; UINT swdLen; UINT libLen; HMODULE result; libLen = strlen(LibName); if(strrchr(LibName,'\\') || strrchr(LibName,'/')) { MYASSERT(FALSE); return NULL; } swdLen = GetSystemDirectoryA(path,MAX_PATH); if((swdLen == 0) || ((swdLen+libLen+1)>=MAX_PATH)) { return NULL; } if(*CharPrevA(path,path+swdLen)!=TEXT('\\')) { path[swdLen++] = TEXT('\\'); } strcpy(path+swdLen,LibName); result = LoadLibraryA(path); if(result) { MYTRACE((DPFLTR_TRACE_LEVEL, TEXT("SetupAPI: delay-loaded %hs.\n"), path)); } else { MYTRACE((DPFLTR_ERROR_LEVEL, TEXT("SetupAPI: Could not delay-load %hs.\n"), path)); } return result; } FARPROC ObtainFnPtr ( IN PCSTR DllName, IN PCSTR ProcName, IN FARPROC Default ) /*++ Routine Description: This routine manages an array of DLL instance handles and returns the proc address of the caller-specified routine. The DLL is loaded and remains loaded until the DLL terminates. This array is not synchronized. Arguments: DllName - The ANSI DLL name to load ProcName - The ANSI procedure name to locate Default - The default procedure, if the export was not found Return Value: The address of the requested function, or NULL if the DLL could not be loaded, or the function is not implemented in the loaded DLL. --*/ { INT i; PSTR DupBuf; FARPROC Address = NULL; // // Search for loaded DLL // for (i = 0 ; i < g_ArraySize ; i++) { if (!lstrcmpiA (DllName, g_DllArray[i].DllName)) { break; } } do { // // If necessary, load the DLL // if (i == g_ArraySize) { if (g_ArraySize == MAX_DLL_ARRAY) { // Constant limit needs to be raised MYASSERT (FALSE); break; } g_DllArray[i].DllInst = DelayLoadLibrary (DllName); if (!g_DllArray[i].DllInst) { break; } DupBuf = (PSTR) MyMalloc (lstrlenA (DllName) + 1); if (!DupBuf) { break; } lstrcpyA (DupBuf, DllName); g_DllArray[i].DllName = DupBuf; g_ArraySize++; } // // Now that DLL is loaded, return the proc address if it exists // Address = GetProcAddress (g_DllArray[i].DllInst, ProcName); } while (FALSE); if (!Address) { return Default; } return Address; } VOID pCleanUpDllArray ( VOID ) /*++ Routine Description: Cleans up the DLL array resources. Arguments: none Return Value: none --*/ { INT i; for (i = 0 ; i < g_ArraySize ; i++) { FreeLibrary (g_DllArray[i].DllInst); MyFree (g_DllArray[i].DllName); } g_ArraySize = 0; } VOID CleanUpStubFns ( VOID ) /*++ Routine Description: Cleans up all resources used by emulation routines and function pointer list. Arguments: none Return Value: none --*/ { pCleanUpDllArray(); } BOOL WINAPI Stub_VerifyVersionInfoA( IN LPOSVERSIONINFOEXA lpVersionInformation, IN DWORD dwTypeMask, IN DWORDLONG dwlConditionMask ) { UNREFERENCED_PARAMETER(lpVersionInformation); UNREFERENCED_PARAMETER(dwTypeMask); UNREFERENCED_PARAMETER(dwlConditionMask); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return(FALSE); } ULONGLONG NTAPI Stub_VerSetConditionMask( IN ULONGLONG ConditionMask, IN DWORD TypeMask, IN BYTE Condition ) { UNREFERENCED_PARAMETER(TypeMask); UNREFERENCED_PARAMETER(Condition); // // Simply return ConditionMask unaltered. (If this API doesn't exist, we // don't expect VerifyVersionInfo to exist either, so that should fail.) // return ConditionMask; } HANDLE WINAPI Stub_SfcConnectToServer( IN LPCWSTR ServerName ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return NULL; } VOID Stub_SfcClose( IN HANDLE RpcHandle ) { return; } DWORD WINAPI Stub_SfcFileException( IN HANDLE RpcHandle, IN PCWSTR FileName, IN DWORD ExpectedChangeType ) { return ERROR_CALL_NOT_IMPLEMENTED; } BOOL WINAPI Stub_SfcIsFileProtected( IN HANDLE RpcHandle, IN LPCWSTR ProtFileName ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } HANDLE WINAPI FirstLoad_SfcConnectToServer( IN LPCWSTR ServerName ) { BOOL ok = FALSE; try { EnterCriticalSection(&InitMutex); if(Dyn_SfcConnectToServer == FirstLoad_SfcConnectToServer) { (FARPROC) Dyn_SfcConnectToServer = ObtainFnPtr ( "sfc_os.dll", (LPCSTR)3, (FARPROC) Stub_SfcConnectToServer ); } LeaveCriticalSection(&InitMutex); ok = TRUE; } except(EXCEPTION_EXECUTE_HANDLER) { } if(ok) { return Dyn_SfcConnectToServer(ServerName); } else { return Stub_SfcConnectToServer(ServerName); } } VOID FirstLoad_SfcClose( IN HANDLE RpcHandle ) { BOOL ok = FALSE; try { EnterCriticalSection(&InitMutex); if(Dyn_SfcClose == FirstLoad_SfcClose) { (FARPROC) Dyn_SfcClose = ObtainFnPtr ( "sfc_os.dll", (LPCSTR)4, (FARPROC) Stub_SfcClose ); } LeaveCriticalSection(&InitMutex); ok = TRUE; } except(EXCEPTION_EXECUTE_HANDLER) { } if(ok) { Dyn_SfcClose(RpcHandle); } return; } DWORD WINAPI FirstLoad_SfcFileException( IN HANDLE RpcHandle, IN PCWSTR FileName, IN DWORD ExpectedChangeType ) { BOOL ok = FALSE; try { EnterCriticalSection(&InitMutex); if(Dyn_SfcFileException == FirstLoad_SfcFileException) { (FARPROC) Dyn_SfcFileException = ObtainFnPtr ( "sfc_os.dll", (LPCSTR)5, (FARPROC) Stub_SfcFileException ); } LeaveCriticalSection(&InitMutex); ok = TRUE; } except(EXCEPTION_EXECUTE_HANDLER) { } if(ok) { return Dyn_SfcFileException(RpcHandle,FileName,ExpectedChangeType); } else { return Stub_SfcFileException(RpcHandle,FileName,ExpectedChangeType); } } BOOL WINAPI FirstLoad_SfcIsFileProtected( IN HANDLE RpcHandle, IN LPCWSTR ProtFileName ) { BOOL ok = FALSE; try { EnterCriticalSection(&InitMutex); if(Dyn_SfcIsFileProtected == FirstLoad_SfcIsFileProtected) { (FARPROC) Dyn_SfcIsFileProtected = ObtainFnPtr ( "sfc_os.dll", "SfcIsFileProtected", (FARPROC) Stub_SfcIsFileProtected ); } LeaveCriticalSection(&InitMutex); ok = TRUE; } except(EXCEPTION_EXECUTE_HANDLER) { } if(ok) { return Dyn_SfcIsFileProtected(RpcHandle,ProtFileName); } else { return Stub_SfcIsFileProtected(RpcHandle,ProtFileName); } } #ifdef ANSI_SETUPAPI CONFIGRET WINAPI Stub_CM_Query_Resource_Conflict_List( OUT PCONFLICT_LIST pclConflictList, IN DEVINST dnDevInst, IN RESOURCEID ResourceID, IN PCVOID ResourceData, IN ULONG ResourceLen, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Free_Resource_Conflict_Handle( IN CONFLICT_LIST clConflictList ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Resource_Conflict_Count( IN CONFLICT_LIST clConflictList, OUT PULONG pulCount ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Resource_Conflict_DetailsA( IN CONFLICT_LIST clConflictList, IN ULONG ulIndex, IN OUT PCONFLICT_DETAILS_A pConflictDetails ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Class_Registry_PropertyA( IN LPGUID ClassGUID, IN ULONG ulProperty, OUT PULONG pulRegDataType, OPTIONAL OUT PVOID Buffer, OPTIONAL IN OUT PULONG pulLength, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Set_Class_Registry_PropertyA( IN LPGUID ClassGUID, IN ULONG ulProperty, IN PCVOID Buffer, OPTIONAL IN ULONG ulLength, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Device_Interface_Alias_ExA( IN PCSTR pszDeviceInterface, IN LPGUID AliasInterfaceGuid, OUT PSTR pszAliasDeviceInterface, IN OUT PULONG pulLength, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Device_Interface_List_ExA( IN LPGUID InterfaceClassGuid, IN DEVINSTID_A pDeviceID, OPTIONAL OUT PCHAR Buffer, IN ULONG BufferLen, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Device_Interface_List_Size_ExA( IN PULONG pulLen, IN LPGUID InterfaceClassGuid, IN DEVINSTID_A pDeviceID, OPTIONAL IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Get_Log_Conf_Priority_Ex( IN LOG_CONF lcLogConf, OUT PPRIORITY pPriority, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Query_And_Remove_SubTree_ExA( IN DEVINST dnAncestor, OUT PPNP_VETO_TYPE pVetoType, OUT PSTR pszVetoName, IN ULONG ulNameLength, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Register_Device_Interface_ExA( IN DEVINST dnDevInst, IN LPGUID InterfaceClassGuid, IN PCSTR pszReference, OPTIONAL OUT PSTR pszDeviceInterface, IN OUT PULONG pulLength, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Set_DevNode_Problem_Ex( IN DEVINST dnDevInst, IN ULONG ulProblem, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } CONFIGRET WINAPI Stub_CM_Unregister_Device_Interface_ExA( IN PCSTR pszDeviceInterface, IN ULONG ulFlags, IN HMACHINE hMachine ) { return CR_CALL_NOT_IMPLEMENTED; } BOOL WINAPI Stub_CryptCATAdminAcquireContext ( OUT HCATADMIN *phCatAdmin, IN const GUID *pgSubsystem, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL WINAPI Stub_CryptCATAdminReleaseContext ( IN HCATADMIN hCatAdmin, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL WINAPI Stub_CryptCATAdminReleaseCatalogContext ( IN HCATADMIN hCatAdmin, IN HCATINFO hCatInfo, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } HCATINFO WINAPI Stub_CryptCATAdminAddCatalog ( IN HCATADMIN hCatAdmin, IN WCHAR *pwszCatalogFile, IN OPTIONAL WCHAR *pwszSelectBaseName, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return NULL; } BOOL WINAPI Stub_CryptCATCatalogInfoFromContext ( IN HCATINFO hCatInfo, IN OUT CATALOG_INFO *psCatInfo, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL WINAPI Stub_CryptCATAdminCalcHashFromFileHandle ( IN HANDLE hFile, IN OUT DWORD *pcbHash, OUT OPTIONAL BYTE *pbHash, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } HCATINFO WINAPI Stub_CryptCATAdminEnumCatalogFromHash( IN HCATADMIN hCatAdmin, IN BYTE *pbHash, IN DWORD cbHash, IN DWORD dwFlags, IN OUT HCATINFO *phPrevCatInfo ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return NULL; } BOOL WINAPI Stub_CryptCATAdminRemoveCatalog( IN HCATADMIN hCatAdmin, IN WCHAR *pwszCatalogFile, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL WINAPI Stub_CryptCATAdminResolveCatalogPath( IN HCATADMIN hCatAdmin, IN WCHAR *pwszCatalogFile, IN OUT CATALOG_INFO *psCatInfo, IN DWORD dwFlags ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } BOOL WINAPI Stub_CertFreeCertificateContext( IN PCCERT_CONTEXT pCertContext ) { SetLastError (ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } LONG WINAPI Stub_WinVerifyTrust( HWND hwnd, GUID *pgActionID, LPVOID pWVTData ) { return ERROR_SUCCESS; } int Stub_wnsprintf( LPTSTR lpOut, int cchLimitIn, LPCTSTR pszFmt, ... ) { // // Win95 doesn't have wnsprintf // in ANSI version of SetupAPI, use CRT instead // va_list argptr; int sz; if(cchLimitIn<=0) { return 0; } va_start(argptr,pszFmt); sz = _vsntprintf(lpOut,cchLimitIn,pszFmt,argptr); if(sz == cchLimitIn) { // // backup // sz = CharPrev(lpOut,lpOut+sz)-lpOut; lpOut[sz] = TEXT('\0'); } return sz; } #endif