-
Notifications
You must be signed in to change notification settings - Fork 13
/
srv_inst.c
162 lines (145 loc) · 3.66 KB
/
srv_inst.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include <windows.h>
#include <stdio.h>
char ____DEVICE_BASENAME[128];
//
// Get system error message string
//
PCSTR SystemMessage(
DWORD nError)
{
static CHAR msg[256];
if (!FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, nError, 0, msg, sizeof(msg), NULL)) {
_snprintf(msg, sizeof(msg),
"Unknown system error %lu (0x%08x)\n", nError, nError);
}
return msg;
}
DWORD WINAPI InstallDriver(
PSTR inst_path,
DWORD nStart)
{
DWORD ret = ERROR_SUCCESS;
SC_HANDLE hScManager; // Service Control Manager
SC_HANDLE hService = NULL; // Service (= Driver)
// Connect to the Service Control Manager
hScManager = OpenSCManager(
NULL, // local machine
NULL, // local database
SC_MANAGER_CREATE_SERVICE); // access required
if (hScManager == NULL)
{
ret = GetLastError();
fprintf(stderr, "failed to connect scm: %s\n", SystemMessage(ret));
goto cleanup;
}
// Create a new service object
hService = CreateService(
hScManager, // service control manager
____DEVICE_BASENAME, // internal service name
____DEVICE_BASENAME, // display name
SERVICE_ALL_ACCESS, // access mode
SERVICE_KERNEL_DRIVER, // service type
nStart, // service start type
SERVICE_ERROR_NORMAL, // start error sevirity
inst_path, // service image file path
NULL, // service group
NULL, // service tag
NULL, // service dependency
NULL, // use LocalSystem account
NULL // password for the account
);
if (!hService)
{
// Failed to create a service object
ret = GetLastError();
fprintf(stderr, "failed to create service: %s\n", SystemMessage(ret));
goto cleanup;
}
cleanup:
// Close the service object handle
if (hService) {
CloseServiceHandle(hService);
}
// Close handle to the service control manager.
if (hScManager) {
CloseServiceHandle(hScManager);
}
return ret;
}
DWORD WINAPI RemoveDriver()
{
SC_HANDLE hScManager; // Service Control Manager
SC_HANDLE hService; // Service (= Driver)
DWORD ret = ERROR_SUCCESS;
// Connect to the Service Control Manager
hScManager = OpenSCManager(NULL, NULL, 0);
if (hScManager == NULL)
{
ret = GetLastError();
fprintf(stderr, "failed to open scm: %s\n", SystemMessage(ret));
return ret;
}
// Open the VFD driver entry in the service database
hService = OpenService(
hScManager, // Service control manager
____DEVICE_BASENAME, // service name
DELETE); // service access mode
if (hService == NULL)
{
ret = GetLastError();
fprintf(stderr, "failed to open service: %s\n", SystemMessage(ret));
goto cleanup;
}
// Remove driver entry from registry
if (!DeleteService(hService))
{
ret = GetLastError();
fprintf(stderr, "failed to delete service: %s\n", SystemMessage(ret));
goto cleanup;
}
cleanup:
// Close the service object handle
if (hService) {
CloseServiceHandle(hService);
}
// Close handle to the service control manager.
if (hScManager) {
CloseServiceHandle(hScManager);
}
return ret;
}
int main(int argc, char* argv[])
{
CHAR system_dir[MAX_PATH];
GetWindowsDirectory(system_dir, sizeof(system_dir));
fprintf(stderr, "system dir: %s\n", system_dir);
if(argc < 3) goto ret;
strcpy(____DEVICE_BASENAME, argv[2]);
printf("service_name=%s\n", ____DEVICE_BASENAME);
switch(argv[1][0])
{
case 'i':
if(argc < 4) goto ret;
printf("file_path=%s\n", argv[3]);
if(InstallDriver(argv[3], SERVICE_DEMAND_START))
{
printf("install error\n");
return 1;
}
break;
case 'r':
if(RemoveDriver())
{
printf("remove error\n");
return 1;
}
break;
}
return 0;
ret:
fprintf(stderr, "Usage: i|r service_name [.sys] \n");
return 1;
}