source: trunk/lib_ir/AgnerTestP/PMCTest/uninstall.cpp @ 4221

Last change on this file since 4221 was 4221, checked in by linmengl, 5 years ago

initial checkin of Agner Fog's performance script

File size: 10.1 KB
Line 
1//                       uninstall.cpp                 © 2009-08-13 Agner Fog
2//
3//
4// Uninstaller for driver MSRDriver32.sys and MSRDriver64.sys used in
5// PMCTest program
6//
7//
8// Compile for console mode Windows.
9// You must have sufficient user privileges to uninstall a driver.
10//
11// © 2009 GNU General Public License www.gnu.org/licenses
12//////////////////////////////////////////////////////////////////////////////
13
14#include "msrdriver.h"
15#include "PMCTest.h"
16#include <conio.h>
17
18// main
19int main(int argc, char* argv[]) {
20    CMSRDriver msr;
21    msr.LoadDriver();
22    msr.UnloadDriver();
23    msr.UnInstallDriver();
24
25    // Optional: wait for key press
26    printf("\npress any key");
27    getch();
28
29    // Exit
30    return 0;
31}
32
33
34//////////////////////////////////////////////////////////////////////
35//
36//        CMSRDriver class member functions
37//            Copied from PMCTestA.cpp
38//
39//////////////////////////////////////////////////////////////////////
40
41// Constructor
42CMSRDriver::CMSRDriver() {
43
44    // Define Driver filename
45    if (Need64BitDriver()) {
46        DriverFileName = "MSRDriver64";
47    }
48    else {
49        DriverFileName = "MSRDriver32";
50    }
51
52    // Define driver symbolic link name
53    DriverSymbolicName = "\\\\.\\slMSRDriver";
54
55    // Get the full path of the driver file name
56    strcpy(DriverFileNameE, DriverFileName);
57    strcat(DriverFileNameE, ".sys");           // append .sys to DriverName
58    ::GetFullPathName(DriverFileNameE, MAX_PATH, DriverFilePath, NULL);
59
60    // Initialize
61    service = NULL;
62    hDriver = NULL;
63    scm     = NULL;
64}
65
66SC_HANDLE CMSRDriver::GetScm() {
67    // Make scm handle
68    if (scm) return scm;  // handle already made
69
70    // Open connection to Windows Service Control Manager (SCM)
71    scm = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
72    if(scm == NULL) {
73        int e = ::GetLastError();
74        if (e == ERROR_ACCESS_DENIED) {
75            printf("\nAccess denied. Please run as administrator\n");
76        }
77        else if (e == 120) {  // function not implemented
78            printf("\nFunction not implemented on this operating system. Windows 2000 or later required.\n");
79        }
80        else {
81            printf("\nCannot load Windows Service Control Manager\nError no. %i", e);
82        }
83    }
84    return scm;
85}
86
87// Destructor
88CMSRDriver::~CMSRDriver() {
89    // Unload driver if not already unloaded and close SCM handle
90
91    //if (hDriver) UnloadDriver();
92    if (service) {
93        ::CloseServiceHandle(service); service = NULL;   
94    }
95    if (scm) {
96        //UnloadDriver();
97        //UnInstallDriver();
98        ::CloseServiceHandle(scm); scm = NULL;
99    }
100}
101
102int CMSRDriver::InstallDriver() {
103    // install MSRDriver
104    if(GetScm() == NULL) return -1;
105
106    // Install driver in database
107    service = ::CreateService(scm, DriverFileNameE, "MSR driver",
108        SERVICE_START + SERVICE_STOP + DELETE, SERVICE_KERNEL_DRIVER,
109        SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, DriverFilePath, 
110        NULL, NULL, NULL, NULL, NULL);
111
112    if(service == NULL) {
113        int e = ::GetLastError();
114        printf("\nCannot install driver %s\nError no. %i", DriverFileNameE, e);
115    }
116    else {
117        printf("\nFirst time: Installing driver %s\n", DriverFileNameE);
118    }
119}
120
121int CMSRDriver::UnInstallDriver() {
122    // uninstall MSRDriver
123    int r = 0, e = 0;
124    GetScm();
125    if (service == 0) {
126        service = ::OpenService(scm, DriverFileNameE, SERVICE_ALL_ACCESS);
127    }
128    if(service == 0) {
129        e = ::GetLastError();
130        if (e == 1060) {
131            printf("\nDriver %s already uninstalled or never installed\n", DriverFileNameE);
132        }
133        else {
134            printf("\nCannot open service, failed to uninstall driver %s\nError no. %i", DriverFileNameE, e);
135        }
136    }
137    else {
138        r = ::DeleteService(service);
139        if (r == 0) {
140            e = ::GetLastError();
141            printf("\nFailed to uninstall driver %s\nError no. %i", DriverFileNameE, e);
142            if (e == 1072) printf("\nDriver already marked for deletion\n");
143        }
144        else {
145            printf("\nUninstalling driver %s\n", DriverFileNameE);
146        }
147        r = ::CloseServiceHandle(service);
148        if (r == 0) {
149            e = ::GetLastError();
150            printf("\nCannot close service\nError no. %i", e);
151        }
152        service = NULL;
153    }
154    return e;
155}
156
157// Load driver
158int CMSRDriver::LoadDriver() {
159    int r = 0, e = 0;
160    // Open a service handle if not already open
161    if (service == 0) {
162        service = ::OpenService(GetScm(), DriverFileNameE, SERVICE_ALL_ACCESS);
163    }
164    if(service == 0) {
165        e = ::GetLastError();
166
167        switch (e) { // Any other error than driver not installed
168        case 1060: // Driver not installed. Install it
169            break;
170        case 6:    // access denied
171            printf("\nAccess denied\n");
172            break;
173        default:  // Any other error
174            printf("\nCannot open service, failed to load driver %s\nError no. %i", DriverFileNameE, e);
175        }
176        return e;
177    }
178
179    // Start the service
180    r = ::StartService(service, 0, NULL);
181    if (r == 0) {
182        e = ::GetLastError();
183        switch (e) {
184        case ERROR_FILE_NOT_FOUND:  // .sys file not found
185            printf("\nDriver file %s not found\n", DriverFileNameE);
186            break;
187
188        case 577:
189            // driver not signed (Vista and Windows 7)
190            printf("\nThe driver %s is not signed by Microsoft\nPlease press F8 during boot and select 'Disable Driver Signature Enforcement'\n", DriverFileNameE);
191            break;
192
193        case 1056:
194            printf("\nDriver already loaded\n");
195            e = 0;
196            break;
197
198        case 1058:
199            printf("\nError: Driver disabled\n");
200            break;
201
202        default:
203            printf("\nCannot load driver %s\nError no. %i", DriverFileNameE, e);
204        }
205    }
206    if (e == 0) {
207        // Get handle to driver
208        hDriver = ::CreateFile(DriverSymbolicName, GENERIC_READ + GENERIC_WRITE,
209            0, NULL, OPEN_EXISTING, 0, NULL);
210
211        if(hDriver == NULL || hDriver == INVALID_HANDLE_VALUE) {
212            hDriver = NULL;
213            e = ::GetLastError();
214            printf("\nCannot load driver\nError no. %i", e);
215        }
216    }
217    return e;
218}
219
220// Unload driver
221int CMSRDriver::UnloadDriver() {
222    int r = 0, e = 0;
223    if(GetScm() == NULL) {
224        return -6;
225    }
226
227    if (hDriver) {
228        r = ::CloseHandle(hDriver); hDriver = NULL;
229        if (r == 0) {
230            e = ::GetLastError();
231            printf("\nCannot close driver handle\nError no. %i", e);
232            return e;
233        }
234        printf("\nUnloading driver");
235    }
236
237    if (service) {
238        SERVICE_STATUS ss;
239        r = ::ControlService(service, SERVICE_CONTROL_STOP, &ss);
240        if (r == 0) {
241            e = ::GetLastError();
242            if (e == 1062) {
243                printf("\nDriver not active\n");
244            }
245            else {
246                printf("\nCannot close driver\nError no. %i", e);
247            }
248            return e;
249        }
250    }
251    return 0;
252}
253
254
255// Access MSR or control registers
256int CMSRDriver::AccessRegisters(void * pnIn, int nInLen, void * pnOut, int nOutLen) {
257    if (nInLen <= 0) return 0;
258
259    const int DeviceType = 0x22;        // FILE_DEVICE_UNKNOWN;
260    const int Function = 0x800;
261    const int Method = 0;               // METHOD_BUFFERED;
262    const int Access = 1 | 2;           // FILE_READ_ACCESS | FILE_WRITE_ACCESS;
263    const int IOCTL_MSR_DRIVER = DeviceType << 16 | Access << 14 | Function << 2 | Method;
264
265    DWORD len = 0;
266
267    // This call results in a call to the driver rutine DispatchControl()
268    int res = ::DeviceIoControl(hDriver, IOCTL_MSR_DRIVER, pnIn, nInLen,
269        pnOut, nOutLen, &len, NULL);
270    if (!res) { 
271        // Error
272        int e = GetLastError();
273        printf("\nCan't access driver. error %i", e);
274        return e;}
275    return 0;
276}
277
278
279// Access MSR or control registers by queue
280int CMSRDriver::AccessRegisters(CMSRInOutQue & q) {
281    // Number of bytes in/out
282    int n = q.GetSize() * sizeof(SMSRInOut); 
283    if (n <= 0) return 0;
284    return AccessRegisters(q.queue, n, q.queue, n);
285}
286
287
288// Get driver name
289LPCTSTR CMSRDriver::GetDriverName() {
290    return DriverFileName;
291}
292
293// Read a MSR register
294int CMSRDriver::MSRRead(int r) {
295    SMSRInOut a;
296    a.msr_command = MSR_READ;
297    a.register_number = r;
298    a.value = 0;
299    AccessRegisters(&a,sizeof(a),&a,sizeof(a));
300    return a.val[0];}
301
302// Write a MSR register
303int CMSRDriver::MSRWrite(int r, int val) {
304    SMSRInOut a;
305    a.msr_command = MSR_WRITE;
306    a.register_number = r;
307    a.value = val;
308    return AccessRegisters(&a,sizeof(a),&a,sizeof(a));}
309
310// Read a control register cr0 or cr4
311size_t CMSRDriver::CRRead(int r) {
312    if (r != 0 && r != 4) return -11;
313    SMSRInOut a;
314    a.msr_command = CR_READ;
315    a.register_number = r;
316    a.value = 0;
317    AccessRegisters(&a,sizeof(a),&a,sizeof(a));
318    return size_t(a.value);}
319
320// Write a control register cr0 or cr4
321int CMSRDriver::CRWrite(int r, size_t val) {
322    if (r != 0 && r != 4) return -12;
323    SMSRInOut a;
324    a.msr_command = CR_WRITE;
325    a.register_number = r;
326    a.value = val;
327    return AccessRegisters(&a,sizeof(a),&a,sizeof(a));}
328
329
330typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
331int CMSRDriver::Need64BitDriver() {
332    // Tell whether we need 32 bit or 64 bit driver.
333    // Return value:
334    // 0: running in 32 bits Windows
335    // 1: running 32 bits application in 64 bits Windows
336    // 2: running in 64 bits Windows
337
338#ifdef _WIN64
339    return 2;
340#else
341
342    LPFN_ISWOW64PROCESS fnIsWow64Process = 
343        (LPFN_ISWOW64PROCESS)GetProcAddress(
344        GetModuleHandle("kernel32"),"IsWow64Process");
345
346    if (fnIsWow64Process) {
347
348        BOOL bIsWow64 = FALSE;
349
350        if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
351            return 0;
352        }
353        return bIsWow64;
354    }
355    return 0;
356#endif
357}
Note: See TracBrowser for help on using the repository browser.