s4:torture: Adapt KDC canon test to Heimdal upstream changes
[samba.git] / third_party / heimdal / lib / roken / win32_version.c
1 #include <config.h>
2 #include "roken.h"
3 #include <psapi.h>
4
5 static DWORD
6 GetVersionInfo(CHAR *filename, CHAR *szOutput, DWORD dwOutput)
7 {
8     DWORD dwVersionHandle;
9     LPVOID pVersionInfo = 0;
10     DWORD retval = 0;
11     LPDWORD pLangInfo = 0;
12     LPTSTR szVersion = 0;
13     UINT len = 0;
14     TCHAR szVerQ[] = TEXT("\\StringFileInfo\\12345678\\FileVersion");
15     DWORD size = GetFileVersionInfoSize(filename, &dwVersionHandle);
16
17     if (!size)
18         return GetLastError();
19
20     pVersionInfo = malloc(size);
21     if (!pVersionInfo)
22         return ERROR_NOT_ENOUGH_MEMORY;
23
24     GetFileVersionInfo(filename, dwVersionHandle, size, pVersionInfo);
25     if (retval = GetLastError())
26         goto cleanup;
27
28     VerQueryValue(pVersionInfo, TEXT("\\VarFileInfo\\Translation"),
29                        (LPVOID*)&pLangInfo, &len);
30     if (retval = GetLastError())
31         goto cleanup;
32
33     wsprintf(szVerQ,
34              TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
35              LOWORD(*pLangInfo), HIWORD(*pLangInfo));
36
37     VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szVersion, &len);
38     if (retval = GetLastError()) {
39         /* try again with language 409 since the old binaries were tagged wrong */
40         wsprintf(szVerQ,
41                   TEXT("\\StringFileInfo\\0409%04x\\FileVersion"),
42                   HIWORD(*pLangInfo));
43
44         VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szVersion, &len);
45         if (retval = GetLastError())
46             goto cleanup;
47     }
48     snprintf(szOutput, dwOutput, TEXT("%s"), szVersion);
49     szOutput[dwOutput - 1] = 0;
50
51  cleanup:
52     free(pVersionInfo);
53
54     return retval;
55 }
56
57 ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
58 win32_getLibraryVersion(const char *libname, char **outname, char **outversion)
59 {
60     CHAR modVersion[128];
61     HMODULE hMods[1024];
62     HANDLE hProcess;
63     DWORD cbNeeded;
64     unsigned int i;
65     int success = -1;
66     HINSTANCE hPSAPI;
67     DWORD (WINAPI *pGetModuleFileNameExA)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize);
68     BOOL (WINAPI *pEnumProcessModules)(HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded);
69
70     if (outversion)
71         *outversion = NULL;
72     if (outname)
73         *outname = NULL;
74
75     hPSAPI = LoadLibrary("psapi");
76     if ( hPSAPI == NULL )
77         return -1;
78
79     if (((FARPROC) pGetModuleFileNameExA =
80           GetProcAddress( hPSAPI, "GetModuleFileNameExA" )) == NULL ||
81          ((FARPROC) pEnumProcessModules =
82            GetProcAddress( hPSAPI, "EnumProcessModules" )) == NULL)
83     {
84         goto out;
85     }
86
87     // Get a list of all the modules in this process.
88     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
89                            FALSE, GetCurrentProcessId());
90
91     if (pEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
92     {
93         for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
94         {
95             char szModName[2048];
96
97             // Get the full path to the module's file.
98             if (pGetModuleFileNameExA(hProcess, hMods[i], szModName, sizeof(szModName)))
99             {
100                 CHAR checkName[1024];
101                 lstrcpy(checkName, szModName);
102                 strlwr(checkName);
103
104                 if (strstr(checkName, libname)) {
105                     if (GetVersionInfo(szModName, modVersion, sizeof(modVersion)) == 0) {
106                         success = 0;
107                         if (outversion) {
108                             *outversion = strdup(modVersion);
109                             if (*outversion == NULL)
110                                 success = -1;
111                         }
112                         if (outname)    {
113                             *outname = strdup(szModName);
114                             if (*outname == NULL)
115                                 success = -1;
116                         }
117                     }
118                     break;
119                 }
120             }
121         }
122     }
123     CloseHandle(hProcess);
124
125   out:
126     FreeLibrary(hPSAPI);
127     return success;
128 }