Allow listing all services.
[nssm.git] / imports.cpp
1 #include "nssm.h"\r
2 \r
3 imports_t imports;\r
4 \r
5 /*\r
6   Try to set up function pointers.\r
7   In this first implementation it is not an error if we can't load them\r
8   because we aren't currently trying to load any functions which we\r
9   absolutely need.  If we later add some indispensible imports we can\r
10   return non-zero here to force an application exit.\r
11 */\r
12 HMODULE get_dll(const TCHAR *dll, unsigned long *error) {\r
13   *error = 0;\r
14 \r
15   HMODULE ret = LoadLibrary(dll);\r
16   if (! ret) {\r
17     *error = GetLastError();\r
18     if (*error != ERROR_PROC_NOT_FOUND) log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_LOADLIBRARY_FAILED, dll, error_string(*error), 0);\r
19   }\r
20 \r
21   return ret;\r
22 }\r
23 \r
24 FARPROC get_import(HMODULE library, const char *function, unsigned long *error) {\r
25   *error = 0;\r
26 \r
27   FARPROC ret = GetProcAddress(library, function);\r
28   if (! ret) {\r
29     *error = GetLastError();\r
30     if (*error != ERROR_PROC_NOT_FOUND) {\r
31       TCHAR *function_name;\r
32 #ifdef UNICODE\r
33       size_t buflen;\r
34       mbstowcs_s(&buflen, NULL, 0, function, _TRUNCATE);\r
35       function_name = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, buflen * sizeof(TCHAR));\r
36       if (function_name) mbstowcs_s(&buflen, function_name, buflen * sizeof(TCHAR), function, _TRUNCATE);\r
37 #else\r
38       function_name = (TCHAR *) function;\r
39 #endif\r
40       log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_GETPROCADDRESS_FAILED, function_name, error_string(*error), 0);\r
41 #ifdef UNICODE\r
42       if (function_name) HeapFree(GetProcessHeap(), 0, function_name);\r
43 #endif\r
44     }\r
45   }\r
46 \r
47   return ret;\r
48 }\r
49 \r
50 int get_imports() {\r
51   unsigned long error;\r
52 \r
53   ZeroMemory(&imports, sizeof(imports));\r
54 \r
55   imports.kernel32 = get_dll(_T("kernel32.dll"), &error);\r
56   if (imports.kernel32) {\r
57     imports.AttachConsole = (AttachConsole_ptr) get_import(imports.kernel32, "AttachConsole", &error);\r
58     if (! imports.AttachConsole) {\r
59       if (error != ERROR_PROC_NOT_FOUND) return 2;\r
60     }\r
61 \r
62     imports.QueryFullProcessImageName = (QueryFullProcessImageName_ptr) get_import(imports.kernel32, QUERYFULLPROCESSIMAGENAME_EXPORT, &error);\r
63     if (! imports.QueryFullProcessImageName) {\r
64       if (error != ERROR_PROC_NOT_FOUND) return 3;\r
65     }\r
66 \r
67     imports.SleepConditionVariableCS = (SleepConditionVariableCS_ptr) get_import(imports.kernel32, "SleepConditionVariableCS", &error);\r
68     if (! imports.SleepConditionVariableCS) {\r
69       if (error != ERROR_PROC_NOT_FOUND) return 4;\r
70     }\r
71 \r
72     imports.WakeConditionVariable = (WakeConditionVariable_ptr) get_import(imports.kernel32, "WakeConditionVariable", &error);\r
73     if (! imports.WakeConditionVariable) {\r
74       if (error != ERROR_PROC_NOT_FOUND) return 5;\r
75     }\r
76   }\r
77   else if (error != ERROR_MOD_NOT_FOUND) return 1;\r
78 \r
79   imports.advapi32 = get_dll(_T("advapi32.dll"), &error);\r
80   if (imports.advapi32) {\r
81     imports.CreateWellKnownSid = (CreateWellKnownSid_ptr) get_import(imports.advapi32, "CreateWellKnownSid", &error);\r
82     if (! imports.CreateWellKnownSid) {\r
83       if (error != ERROR_PROC_NOT_FOUND) return 7;\r
84     }\r
85     imports.IsWellKnownSid = (IsWellKnownSid_ptr) get_import(imports.advapi32, "IsWellKnownSid", &error);\r
86     if (! imports.IsWellKnownSid) {\r
87       if (error != ERROR_PROC_NOT_FOUND) return 8;\r
88     }\r
89   }\r
90   else if (error != ERROR_MOD_NOT_FOUND) return 6;\r
91 \r
92   return 0;\r
93 }\r
94 \r
95 void free_imports() {\r
96   if (imports.kernel32) FreeLibrary(imports.kernel32);\r
97   if (imports.advapi32) FreeLibrary(imports.advapi32);\r
98   ZeroMemory(&imports, sizeof(imports));\r
99 }\r