ref: b9e18229624500d6d2a6112a5c00882d7b7051de
parent: 662ad8cbcdc389b41693fbe2fcf567275d3408e7
author: Simon Howard <fraggle@gmail.com>
date: Sun Mar 7 19:51:00 EST 2010
Load advapi32.dll pointers dynamically at runtime. This should fix any potential problems with that library not existing on Win9x. Subversion-branch: /branches/opl-branch Subversion-revision: 1877
--- a/opl/ioperm_sys.c
+++ b/opl/ioperm_sys.c
@@ -49,11 +49,93 @@
int turn_on;
};
+// Function pointers for advapi32.dll. This DLL does not exist on
+// Windows 9x, so they are dynamically loaded from the DLL at runtime.
+
+static SC_HANDLE WINAPI (*MyOpenSCManagerW)(wchar_t *lpMachineName,
+ wchar_t *lpDatabaseName,
+ DWORD dwDesiredAccess) = NULL;
+static SC_HANDLE WINAPI (*MyCreateServiceW)(SC_HANDLE hSCManager,
+ wchar_t *lpServiceName,
+ wchar_t *lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ wchar_t *lpBinaryPathName,
+ wchar_t *lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ wchar_t *lpDependencies,
+ wchar_t *lpServiceStartName,
+ wchar_t *lpPassword);
+static SC_HANDLE WINAPI (*MyOpenServiceW)(SC_HANDLE hSCManager,
+ wchar_t *lpServiceName,
+ DWORD dwDesiredAccess);
+static BOOL WINAPI (*MyStartServiceW)(SC_HANDLE hService,
+ DWORD dwNumServiceArgs,
+ wchar_t **lpServiceArgVectors);
+static BOOL WINAPI (*MyControlService)(SC_HANDLE hService,
+ DWORD dwControl,
+ LPSERVICE_STATUS lpServiceStatus);
+static BOOL WINAPI (*MyCloseServiceHandle)(SC_HANDLE hSCObject);
+static BOOL WINAPI (*MyDeleteService)(SC_HANDLE hService);
+
+static struct
+{
+ char *name;
+ void **fn;
+} dll_functions[] = {
+ { "OpenSCManagerW", (void **) &MyOpenSCManagerW },
+ { "CreateServiceW", (void **) &MyCreateServiceW },
+ { "OpenServiceW", (void **) &MyOpenServiceW },
+ { "StartServiceW", (void **) &MyStartServiceW },
+ { "ControlService", (void **) &MyControlService },
+ { "CloseServiceHandle", (void **) &MyCloseServiceHandle },
+ { "DeleteService", (void **) &MyDeleteService },
+};
+
+// Globals
+
static SC_HANDLE scm = NULL;
static SC_HANDLE svc = NULL;
static int service_was_created = 0;
static int service_was_started = 0;
+static int LoadLibraryPointers(void)
+{
+ HMODULE dll;
+ int i;
+
+ // Already loaded?
+
+ if (MyOpenSCManagerW != NULL)
+ {
+ return 1;
+ }
+
+ dll = LoadLibraryW(L"advapi32.dll");
+
+ if (dll == NULL)
+ {
+ fprintf(stderr, "LoadLibraryPointers: Failed to open advapi32.dll\n");
+ return 0;
+ }
+
+ for (i = 0; i < sizeof(dll_functions) / sizeof(*dll_functions); ++i)
+ {
+ *dll_functions[i].fn = GetProcAddress(dll, dll_functions[i].name);
+
+ if (*dll_functions[i].fn == NULL)
+ {
+ fprintf(stderr, "LoadLibraryPointers: Failed to get address "
+ "for '%s'\n", dll_functions[i].name);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
int IOperm_EnablePortRange(unsigned int from, unsigned int num, int turn_on)
{
HANDLE h;
@@ -99,8 +181,13 @@
int error;
int result = 1;
- scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+ if (!LoadLibraryPointers())
+ {
+ return 0;
+ }
+ scm = MyOpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+
if (scm == NULL)
{
error = GetLastError();
@@ -115,19 +202,19 @@
// Create the service.
- svc = CreateServiceW(scm,
- L"ioperm",
- L"ioperm support for Cygwin driver",
- SERVICE_ALL_ACCESS,
- SERVICE_KERNEL_DRIVER,
- SERVICE_AUTO_START,
- SERVICE_ERROR_NORMAL,
- driver_path,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
+ svc = MyCreateServiceW(scm,
+ L"ioperm",
+ L"ioperm support for Cygwin driver",
+ SERVICE_ALL_ACCESS,
+ SERVICE_KERNEL_DRIVER,
+ SERVICE_AUTO_START,
+ SERVICE_ERROR_NORMAL,
+ driver_path,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
if (svc == NULL)
{
@@ -141,7 +228,7 @@
}
else
{
- svc = OpenServiceW(scm, L"ioperm", SERVICE_ALL_ACCESS);
+ svc = MyOpenServiceW(scm, L"ioperm", SERVICE_ALL_ACCESS);
if (svc == NULL)
{
@@ -155,7 +242,7 @@
if (svc == NULL)
{
- CloseServiceHandle(scm);
+ MyCloseServiceHandle(scm);
return 0;
}
}
@@ -167,7 +254,7 @@
// Start the service. If the service already existed, it might have
// already been running as well.
- if (!StartServiceW(svc, 0, NULL))
+ if (!MyStartServiceW(svc, 0, NULL))
{
error = GetLastError();
@@ -210,7 +297,7 @@
if (service_was_started)
{
- if (!ControlService(svc, SERVICE_CONTROL_STOP, &stat))
+ if (!MyControlService(svc, SERVICE_CONTROL_STOP, &stat))
{
error = GetLastError();
@@ -234,7 +321,7 @@
if (service_was_created)
{
- if (!DeleteService(svc))
+ if (!MyDeleteService(svc))
{
error = GetLastError();
@@ -254,13 +341,13 @@
if (svc != NULL)
{
- CloseServiceHandle(svc);
+ MyCloseServiceHandle(svc);
svc = NULL;
}
if (scm != NULL)
{
- CloseServiceHandle(scm);
+ MyCloseServiceHandle(scm);
scm = NULL;
}