[project] Rename winvblock__uint32 back to UINT32
[people/sha0/winvblock.git] / src / loader / loader.c
1 /**
2  * Copyright 2006-2008, V.
3  * Portions copyright (C) 2009-2011, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
4  * For WinAoE contact information, see http://winaoe.org/
5  *
6  * This file is part of WinVBlock, derived from WinAoE.
7  *
8  * WinVBlock is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * WinVBlock is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with WinVBlock.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 /**
23  * @file
24  *
25  * Driver installation
26  *
27  */
28
29 #include <stdio.h>
30 #include <windows.h>
31 #include <Setupapi.h>
32 #include <newdev.h>
33
34 #include "winvblock.h"
35 #include "portable.h"
36
37 #define MAX_CLASS_NAME_LEN 64
38
39 /* typedef BOOL WINAPI (*PROC)(HWND, LPCTSTR, LPCTSTR, DWORD, PBOOL OPTIONAL);
40  */
41
42 static void
43 DisplayError (
44   char *String
45  )
46 {
47   CHAR ErrorString[1024];
48   UINT32 ErrorCode = GetLastError();
49
50   printf ( "Error: %s\n", String );
51   printf ( "GetLastError: 0x%08x (%d)\n", ErrorCode, ( int )ErrorCode );
52   if ( FormatMessage
53        ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
54          ErrorCode, MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ),
55          ( LPTSTR ) ErrorString, sizeof ( ErrorString ), NULL ) )
56     printf ( "%s", ErrorString );
57 }
58
59 int
60 main (
61   int argc,
62   char **argv,
63   char **envp
64  )
65 {
66   HDEVINFO DeviceInfoSet = 0;
67   SP_DEVINFO_DATA DeviceInfoData;
68   GUID ClassGUID;
69   TCHAR ClassName[MAX_CLASS_NAME_LEN];
70   HINSTANCE Library;
71   PROC UpdateDriverForPlugAndPlayDevicesA;
72   BOOL RebootRequired = FALSE;
73   TCHAR FullFilePath[1024];
74
75   if ( !GetFullPathName
76        ( "winvblk.inf", sizeof ( FullFilePath ), FullFilePath, NULL ) )
77     goto GetFullPathNameError;
78   if ( ( Library = LoadLibrary ( "newdev.dll" ) ) == NULL )
79     goto LoadLibraryError;
80   if ( ( UpdateDriverForPlugAndPlayDevicesA =
81          GetProcAddress ( Library,
82                           "UpdateDriverForPlugAndPlayDevicesA" ) ) == NULL )
83     goto GetProcAddressError;
84
85   if ( !SetupDiGetINFClass
86        ( FullFilePath, &ClassGUID, ClassName, sizeof ( ClassName ), 0 ) )
87     goto GetINFClassError;
88   if ( ( DeviceInfoSet =
89          SetupDiCreateDeviceInfoList ( &ClassGUID,
90                                        0 ) ) == INVALID_HANDLE_VALUE )
91     goto CreateDeviceInfoListError;
92   DeviceInfoData.cbSize = sizeof ( SP_DEVINFO_DATA );
93   if ( !SetupDiCreateDeviceInfo
94        ( DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID,
95          &DeviceInfoData ) )
96     goto CreateDeviceInfoError;
97   if ( !SetupDiSetDeviceRegistryProperty
98        ( DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID,
99          ( LPBYTE ) WVL_M_LIT "\0\0\0",
100          ( lstrlen ( WVL_M_LIT "\0\0\0" ) + 1 +
101            1 ) * sizeof ( TCHAR ) ) )
102     goto SetDeviceRegistryPropertyError;
103   if ( !SetupDiCallClassInstaller
104        ( DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData ) )
105     goto CallClassInstallerREGISTERDEVICEError;
106
107   if ( !UpdateDriverForPlugAndPlayDevices
108        ( 0, WVL_M_LIT "\0\0\0", FullFilePath, INSTALLFLAG_FORCE,
109          &RebootRequired ) )
110     {
111       DWORD err = GetLastError (  );
112       DisplayError ( "UpdateDriverForPlugAndPlayDevices" );
113       if ( !SetupDiCallClassInstaller
114            ( DIF_REMOVE, DeviceInfoSet, &DeviceInfoData ) )
115         DisplayError ( "CallClassInstaller(REMOVE)" );
116       SetLastError ( err );
117     }
118   if ( RebootRequired )
119     printf ( "Need reboot\n" );
120
121   printf ( "Press enter to remove\n" );
122   getchar (  );
123   if ( !SetupDiCallClassInstaller
124        ( DIF_REMOVE, DeviceInfoSet, &DeviceInfoData ) )
125     DisplayError ( "CallClassInstaller(REMOVE)" );
126   return 0;
127
128 GetFullPathNameError:
129   DisplayError ( "GetFullPathName" );
130   goto end;
131 LoadLibraryError:
132   DisplayError ( "LoadLibrary" );
133   goto end;
134 GetProcAddressError:
135   DisplayError ( "GetProcAddress" );
136   goto end;
137 GetINFClassError:
138   DisplayError ( "GetINFClass" );
139   goto end;
140 CreateDeviceInfoListError:
141   DisplayError ( "CreateDeviceInfoList" );
142   goto end;
143
144 CreateDeviceInfoError:
145   DisplayError ( "CreateDeviceInfo" );
146   goto cleanup_DeviceInfo;
147 SetDeviceRegistryPropertyError:
148   DisplayError ( "SetDeviceRegistryProperty" );
149   goto cleanup_DeviceInfo;
150 CallClassInstallerREGISTERDEVICEError:
151   DisplayError ( "CallClassInstaller(REGISTERDEVICE)" );
152   goto cleanup_DeviceInfo;
153
154 cleanup_DeviceInfo:
155   SetupDiDestroyDeviceInfoList ( DeviceInfoSet );
156 end:
157   printf ( "Press enter to exit\n" );
158   getchar (  );
159   return 0;
160 }