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;
}
--
⑨