Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

291 lines
8.1 KiB

  1. #include <windows.h>
  2. #include <setupapi.h>
  3. #include <spapip.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ole2.h>
  8. #include <excppkg.h>
  9. #define PACKAGE_DIRECTORY L"%windir%\\RegisteredPackages\\"
  10. BOOL
  11. CALLBACK
  12. pComponentLister(
  13. IN const PSETUP_OS_COMPONENT_DATA SetupOsComponentData,
  14. IN const PSETUP_OS_EXCEPTION_DATA SetupOsExceptionData,
  15. IN OUT DWORD_PTR Context
  16. )
  17. {
  18. PDWORD Count = (PDWORD) Context;
  19. PWSTR GuidString;
  20. StringFromIID(&SetupOsComponentData->ComponentGuid, &GuidString);
  21. wprintf( L"Component Data\n\tName: %ws\n\tGuid: %ws\n\tVersionMajor: %d\n\tVersionMinor: %d\n",
  22. SetupOsComponentData->FriendlyName,
  23. GuidString,
  24. SetupOsComponentData->VersionMajor,
  25. SetupOsComponentData->VersionMinor);
  26. wprintf( L"ExceptionData\n\tInf: %ws\n\tCatalog: %ws\n",
  27. SetupOsExceptionData->ExceptionInfName,
  28. SetupOsExceptionData->CatalogFileName);
  29. *Count += 1;
  30. CoTaskMemFree( GuidString );
  31. return(TRUE);
  32. }
  33. VOID
  34. Usage(
  35. VOID
  36. )
  37. {
  38. wprintf(L"test <infname>\n");
  39. }
  40. int
  41. __cdecl
  42. main(
  43. IN int argc,
  44. IN char *argv[]
  45. )
  46. {
  47. WCHAR Path[MAX_PATH];
  48. SETUP_OS_COMPONENT_DATA ComponentData,cd;
  49. SETUP_OS_EXCEPTION_DATA ExceptionData,ed;
  50. PWSTR s,t;
  51. GUID MyGuid;
  52. PCWSTR GuidString;
  53. PWSTR AGuidString;
  54. DWORD VersionInInf, RegisteredVersion;
  55. BOOL ForcePackageUninstall;
  56. WCHAR SourcePath[MAX_PATH];
  57. DWORD i;
  58. PCSTR InfName;
  59. PCWSTR InfSrcPath,FriendlyName;
  60. PCWSTR PackageCatName, PackageInfName;
  61. HINF hInf;
  62. INFCONTEXT Context;
  63. HSPFILEQ hFileQueue;
  64. PVOID QueueContext;
  65. if (argc < 2) {
  66. wprintf(L"Missing arguments!\n");
  67. Usage();
  68. return 1;
  69. }
  70. InfName = argv[1];
  71. ForcePackageUninstall = (argc == 3);
  72. hInf = SetupOpenInfFileA( InfName, NULL, INF_STYLE_WIN4, NULL );
  73. if (hInf == INVALID_HANDLE_VALUE) {
  74. wprintf(L"Couldn't open inf, ec = %x\n", GetLastError());
  75. Usage();
  76. return 1;
  77. }
  78. if (!SetupFindFirstLine(hInf,
  79. L"Version",
  80. L"ComponentId",
  81. &Context)) {
  82. wprintf(L"Couldn't find ComponentId in inf, ec = %x\n", GetLastError());
  83. SetupCloseInfFile( hInf );
  84. Usage();
  85. return 1;
  86. }
  87. GuidString = pSetupGetField( &Context, 1);
  88. if (!SetupFindFirstLine(hInf,
  89. L"Version",
  90. L"ComponentVersion",
  91. &Context)) {
  92. wprintf(L"Couldn't find ComponentVersion in inf, ec = %x\n", GetLastError());
  93. SetupCloseInfFile( hInf );
  94. Usage();
  95. return 1;
  96. }
  97. SetupGetIntField( &Context, 1, &VersionInInf);
  98. SetupFindFirstLine(hInf, L"DefaultInstall", L"InfName", &Context);
  99. PackageInfName = pSetupGetField( &Context, 1);
  100. SetupFindFirstLine(hInf, L"DefaultInstall", L"CatalogName", &Context);
  101. PackageCatName = pSetupGetField( &Context, 1);
  102. //
  103. // 1. Make sure my package isn't already installed.
  104. //
  105. ComponentData.SizeOfStruct = sizeof(SETUP_OS_COMPONENT_DATA);
  106. ExceptionData.SizeOfStruct = sizeof(SETUP_OS_EXCEPTION_DATA);
  107. IIDFromString( (PWSTR)GuidString, &MyGuid);
  108. if (SetupQueryRegisteredOsComponent(
  109. &MyGuid,
  110. &ComponentData,
  111. &ExceptionData)) {
  112. wprintf(L"My component is already registered with the OS, removing it!\n");
  113. //
  114. // 2. unregister any packages that are superceded by my package
  115. //
  116. RegisteredVersion = MAKELONG(
  117. ComponentData.VersionMajor,
  118. ComponentData.VersionMinor );
  119. if (RegisteredVersion < VersionInInf || ForcePackageUninstall) {
  120. if (!SetupUnRegisterOsComponent(&MyGuid)) {
  121. SetupCloseInfFile( hInf );
  122. wprintf(L"couldn't remove my component, ec = %d\n", GetLastError());
  123. return 1;
  124. }
  125. }
  126. }
  127. //
  128. // 3. Install my package
  129. //
  130. //
  131. // 3a. copy my exception package to the appropriate location
  132. //
  133. //
  134. // 3a.1 make sure the main package directory exists
  135. //
  136. ExpandEnvironmentStrings(
  137. PACKAGE_DIRECTORY,
  138. Path,
  139. sizeof(Path)/sizeof(WCHAR));
  140. CreateDirectory( Path, NULL );
  141. //
  142. // 3a.2 now create my package directory
  143. //
  144. wcscat( Path, GuidString );
  145. CreateDirectory( Path, NULL );
  146. if (!SetupFindFirstLine(hInf, L"DefaultInstall", L"InstallSource", &Context)) {
  147. wprintf(L"Couldn't find InstallSource in INF\n");
  148. SetupCloseInfFile( hInf );
  149. return 1;
  150. }
  151. InfSrcPath = pSetupGetField( &Context, 1);
  152. ExpandEnvironmentStrings(InfSrcPath,SourcePath,sizeof(SourcePath)/sizeof(WCHAR));
  153. hFileQueue = SetupOpenFileQueue();
  154. QueueContext = SetupInitDefaultQueueCallbackEx( NULL, INVALID_HANDLE_VALUE, 0, 0, NULL);
  155. SetupSetDirectoryId(hInf, DIRID_USER, Path);
  156. if (!SetupInstallFilesFromInfSection(
  157. hInf,
  158. NULL,
  159. hFileQueue,
  160. L"DefaultInstall",
  161. SourcePath,
  162. SP_COPY_NEWER)) {
  163. wprintf(L"failed to SetupInstallFilesFromInfSection, ec = %x\n", GetLastError());
  164. SetupCloseFileQueue(hFileQueue);
  165. SetupTermDefaultQueueCallback( QueueContext );
  166. SetupCloseInfFile( hInf );
  167. return 1;
  168. }
  169. if (!SetupCommitFileQueue(NULL, hFileQueue, SetupDefaultQueueCallback, QueueContext)) {
  170. wprintf(L"failed to SetupCommitFileQueue, ec = %x\n", GetLastError());
  171. SetupCloseFileQueue(hFileQueue);
  172. SetupTermDefaultQueueCallback( QueueContext );
  173. SetupCloseInfFile( hInf );
  174. return 1;
  175. }
  176. SetupCloseFileQueue(hFileQueue);
  177. SetupTermDefaultQueueCallback( QueueContext );
  178. SetupFindFirstLine(hInf, L"Version", L"FriendlyName", &Context);
  179. FriendlyName = pSetupGetField( &Context, 1);
  180. //
  181. // 3b. register the package
  182. //
  183. ComponentData.VersionMajor = HIWORD(VersionInInf);
  184. ComponentData.VersionMinor = LOWORD(VersionInInf);
  185. RtlMoveMemory(&ComponentData.ComponentGuid, &MyGuid,sizeof(GUID));
  186. wcscpy(ComponentData.FriendlyName, FriendlyName);
  187. wcscpy( Path, PACKAGE_DIRECTORY );
  188. wcscat( Path, GuidString );
  189. wcscat( Path, L"\\" );
  190. t = wcsrchr( Path, L'\\' );
  191. t += 1;
  192. *t = '\0';
  193. wcscat( t, PackageInfName );
  194. wcscpy(ExceptionData.ExceptionInfName, Path);
  195. *t = '\0';
  196. wcscat( t, PackageCatName );
  197. wcscpy(ExceptionData.CatalogFileName, Path);
  198. if (!SetupRegisterOsComponent(&ComponentData, &ExceptionData)) {
  199. wprintf( L"Failed to register component, ec = %d\n", GetLastError() );
  200. SetupCloseInfFile( hInf );
  201. return 1;
  202. }
  203. //
  204. // 4. retrieve my package
  205. //
  206. cd.SizeOfStruct = sizeof(SETUP_OS_COMPONENT_DATA);
  207. ed.SizeOfStruct = sizeof(SETUP_OS_EXCEPTION_DATA);
  208. if (!SetupQueryRegisteredOsComponent(
  209. &MyGuid,
  210. &cd,
  211. &ed)) {
  212. wprintf( L"Failed to register component, ec = %d\n", GetLastError() );
  213. SetupCloseInfFile( hInf );
  214. return 1;
  215. }
  216. StringFromIID(&cd.ComponentGuid, &AGuidString);
  217. wprintf( L"Component Data\n\tName: %ws\n\tGuid: %ws\n\tVersionMajor: %d\n\tVersionMinor: %d\n",
  218. cd.FriendlyName,AGuidString,cd.VersionMajor,cd.VersionMinor);
  219. wprintf( L"ExceptionData\n\tInf: %ws\n\tCatalog: %ws\n",
  220. ed.ExceptionInfName,ed.CatalogFileName);
  221. CoTaskMemFree( AGuidString );
  222. //
  223. // enumerate packages
  224. //
  225. i = 0;
  226. if (!SetupEnumerateRegisteredOsComponents( pComponentLister, (DWORD_PTR)&i)) {
  227. wprintf( L"Failed to enumerate components, ec = %d\n", GetLastError() );
  228. SetupCloseInfFile( hInf );
  229. return 1;
  230. }
  231. wprintf( L"Done (%d enumerated components)!!!\n", i );
  232. SetupCloseInfFile( hInf );
  233. return 0;
  234. }
  235.