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.

1184 lines
40 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. inftrans.c
  5. Abstract:
  6. Implements a basic secure server transport module
  7. Author:
  8. Jim Schmidt (jimschm) 08-Mar-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "logmsg.h"
  17. #define DBG_INFTRANS "InfTrans"
  18. //
  19. // Strings
  20. //
  21. #define S_TRANSPORT_DIR TEXT("USMT2I.UNC")
  22. #define S_TRANSPORT_INF_FILE TEXT("migration.inf")
  23. #define S_TRANSPORT_STATUS_FILE TEXT("status")
  24. #define S_DETAILS_PREFIX TEXT("details")
  25. #define S_DATABASEFILE_LITE TEXT("|MainDatabaseFile\\LITE") // pipe is to decorate for uniqueness
  26. //
  27. // Constants
  28. //
  29. #define TRFLAG_FILE 0x01
  30. #define TRFLAG_MEMORY 0x02
  31. #define INFTR_SIG 0x55534D32 //USM2
  32. #define TRSTATUS_DIRTY 0x00000001
  33. #define TRSTATUS_READY 0x00000002
  34. #define TRSTATUS_LOCKED 0x00000003
  35. //
  36. // Macros
  37. //
  38. // None
  39. //
  40. // Types
  41. //
  42. typedef struct {
  43. TCHAR TempFile [MAX_PATH];
  44. PCVOID AllocPtr;
  45. PCVOID DetailsPtr;
  46. HANDLE FileHandle;
  47. HANDLE MapHandle;
  48. } ALLOCSTATE, *PALLOCSTATE;
  49. //
  50. // Globals
  51. //
  52. MIG_TRANSPORTSTORAGEID g_ReliableStorageId;
  53. PCTSTR g_InfTransTransportPath = NULL;
  54. PCTSTR g_InfTransTransportStatus = NULL;
  55. HANDLE g_InfTransTransportStatusHandle = NULL;
  56. UINT g_Platform;
  57. MIG_PROGRESSSLICEID g_DatabaseSlice;
  58. MIG_PROGRESSSLICEID g_PersistentSlice;
  59. //
  60. // Macro expansion list
  61. //
  62. // None
  63. //
  64. // Private function prototypes
  65. //
  66. // see unctrans.h
  67. //
  68. // Macro expansion definition
  69. //
  70. // None
  71. //
  72. // Code
  73. //
  74. BOOL
  75. pSetInfTransStatus (
  76. IN HANDLE TrJournalHandle,
  77. IN DWORD Status
  78. )
  79. {
  80. DWORD signature = INFTR_SIG;
  81. BOOL result = FALSE;
  82. if (BfSetFilePointer (TrJournalHandle, 0)) {
  83. result = TRUE;
  84. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&signature), sizeof (DWORD));
  85. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&Status), sizeof (DWORD));
  86. result = result && FlushFileBuffers (TrJournalHandle);
  87. }
  88. return TRUE;
  89. }
  90. DWORD
  91. pGetInfTransStatus (
  92. IN PCTSTR TrJournal
  93. )
  94. {
  95. HANDLE trJrnHandle;
  96. DWORD signature = 0;
  97. DWORD result = 0;
  98. if (TrJournal && TrJournal [0]) {
  99. trJrnHandle = BfOpenReadFile (TrJournal);
  100. if (trJrnHandle) {
  101. if (BfSetFilePointer (trJrnHandle, 0)) {
  102. if (BfReadFile (trJrnHandle, (PBYTE)(&signature), sizeof (DWORD))) {
  103. if (signature == INFTR_SIG) {
  104. if (!BfReadFile (trJrnHandle, (PBYTE)(&result), sizeof (DWORD))) {
  105. result = 0;
  106. }
  107. }
  108. }
  109. }
  110. CloseHandle (trJrnHandle);
  111. } else {
  112. if (GetLastError () == ERROR_ACCESS_DENIED) {
  113. result = TRSTATUS_LOCKED;
  114. }
  115. }
  116. }
  117. return result;
  118. }
  119. BOOL
  120. WINAPI
  121. InfTransTransportInitialize (
  122. IN PMIG_LOGCALLBACK LogCallback
  123. )
  124. {
  125. //
  126. // Initialize globals
  127. //
  128. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  129. g_ReliableStorageId = IsmRegisterTransport (S_RELIABLE_STORAGE_TRANSPORT);
  130. return TRUE;
  131. }
  132. VOID
  133. WINAPI
  134. InfTransTransportEstimateProgressBar (
  135. MIG_PLATFORMTYPEID PlatformTypeId
  136. )
  137. {
  138. DEBUGMSG ((DBG_VERBOSE, "Assuming transport download has no progress impact"));
  139. }
  140. BOOL
  141. WINAPI
  142. InfTransTransportQueryCapabilities (
  143. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  144. OUT PMIG_TRANSPORTTYPE TransportType,
  145. OUT PMIG_TRANSPORTCAPABILITIES Capabilities,
  146. OUT PCTSTR *FriendlyDescription
  147. )
  148. {
  149. if (TransportStorageId != g_ReliableStorageId) {
  150. return FALSE;
  151. }
  152. *TransportType = TRANSPORTTYPE_LIGHT;
  153. *Capabilities = 0;
  154. *FriendlyDescription = TEXT("Another Computer on the Network");
  155. return TRUE;
  156. }
  157. BOOL
  158. WINAPI
  159. InfTransTransportSetStorage (
  160. IN MIG_PLATFORMTYPEID Platform,
  161. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  162. IN MIG_TRANSPORTCAPABILITIES RequiredCapabilities,
  163. IN PCTSTR StoragePath,
  164. OUT PBOOL Valid,
  165. OUT PBOOL ImageExists
  166. )
  167. {
  168. PCTSTR transportPath;
  169. PCTSTR transportStatus;
  170. MIG_OBJECTSTRINGHANDLE encodedPath;
  171. DWORD status;
  172. BOOL result = FALSE;
  173. if (Valid) {
  174. *Valid = FALSE;
  175. }
  176. if (ImageExists) {
  177. *ImageExists = FALSE;
  178. }
  179. if (TransportStorageId == g_ReliableStorageId && !RequiredCapabilities) {
  180. transportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
  181. transportStatus = JoinPaths (transportPath, S_TRANSPORT_STATUS_FILE);
  182. if (!DoesFileExist (transportPath)) {
  183. // we require UNC path or a full path (like c:\...)
  184. if (transportPath[0] == '\\' && transportPath[1] == '\\') {
  185. // this is a UNC path
  186. *Valid = TRUE;
  187. } else if (transportPath[1] == ':') {
  188. // this is a normal full path
  189. *Valid = TRUE;
  190. } else {
  191. *Valid = FALSE;
  192. }
  193. *ImageExists = FALSE;
  194. } else {
  195. status = pGetInfTransStatus (transportStatus);
  196. switch (status) {
  197. case TRSTATUS_LOCKED:
  198. *ImageExists = TRUE;
  199. *Valid = FALSE;
  200. break;
  201. case TRSTATUS_READY:
  202. *ImageExists = TRUE;
  203. *Valid = TRUE;
  204. break;
  205. case TRSTATUS_DIRTY:
  206. *ImageExists = FALSE;
  207. *Valid = TRUE;
  208. break;
  209. default:
  210. *ImageExists = FALSE;
  211. *Valid = TRUE;
  212. }
  213. }
  214. FreePathString (transportStatus);
  215. FreePathString (transportPath);
  216. result = TRUE;
  217. }
  218. if (result && *Valid) {
  219. if (g_InfTransTransportPath) {
  220. FreePathString (g_InfTransTransportPath);
  221. g_InfTransTransportPath = NULL;
  222. }
  223. g_InfTransTransportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
  224. g_InfTransTransportStatus = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_STATUS_FILE);
  225. encodedPath = IsmCreateSimpleObjectPattern (g_InfTransTransportPath, FALSE, NULL, FALSE);
  226. if (encodedPath) {
  227. IsmRegisterStaticExclusion (MIG_FILE_TYPE, encodedPath);
  228. IsmDestroyObjectHandle (encodedPath);
  229. }
  230. }
  231. return result;
  232. }
  233. BOOL
  234. pInfTransSaveDetails (
  235. IN PCTSTR DecoratedObject,
  236. IN PMIG_DETAILS Details
  237. )
  238. {
  239. PCTSTR key;
  240. BOOL b;
  241. if ((!Details) || (!Details->DetailsSize)) {
  242. return TRUE;
  243. }
  244. key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
  245. b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
  246. FreeText (key);
  247. return b;
  248. }
  249. PCTSTR
  250. pInfTransBuildDecoratedObject (
  251. IN MIG_OBJECTTYPEID ObjectTypeId,
  252. IN ENCODEDSTRHANDLE ObjectName
  253. )
  254. {
  255. TCHAR prefix[32];
  256. wsprintf (prefix, TEXT("%u"), ObjectTypeId & (~PLATFORM_MASK));
  257. return JoinPaths (prefix, ObjectName);
  258. }
  259. VOID
  260. pInfTransDestroyDecoratedObject (
  261. IN PCTSTR String
  262. )
  263. {
  264. FreePathString (String);
  265. }
  266. BOOL
  267. pObjectNameToFileName (
  268. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  269. OUT PCTSTR *FileName,
  270. OUT PCTSTR *DirName OPTIONAL
  271. )
  272. {
  273. PCTSTR node, leaf;
  274. PCTSTR newNode, dirName;
  275. BOOL result = FALSE;
  276. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  277. newNode = StringSearchAndReplace (node, TEXT(":"), TEXT(""));
  278. if (newNode) {
  279. result = TRUE;
  280. if (leaf) {
  281. dirName = JoinPaths (g_InfTransTransportPath, newNode);
  282. *FileName = JoinPaths (dirName, leaf);
  283. if (!DirName) {
  284. FreePathString (dirName);
  285. } else {
  286. *DirName = dirName;
  287. }
  288. FreePathString (newNode);
  289. } else {
  290. *FileName = JoinPaths (g_InfTransTransportPath, newNode);
  291. if (DirName) {
  292. *DirName = *FileName;
  293. }
  294. FreePathString (newNode);
  295. }
  296. } else {
  297. dirName = JoinPaths (g_InfTransTransportPath, node);
  298. *FileName = JoinPaths (dirName, leaf);
  299. FreePathString (dirName);
  300. if (DirName) {
  301. *DirName = JoinPaths (g_InfTransTransportPath, node);
  302. }
  303. result = TRUE;
  304. }
  305. IsmDestroyObjectString (node);
  306. IsmDestroyObjectString (leaf);
  307. }
  308. return result;
  309. }
  310. BOOL
  311. pIsShortFileName (
  312. IN MIG_OBJECTTYPEID ObjectTypeId,
  313. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  314. IN PCTSTR TempDir
  315. )
  316. {
  317. PCTSTR nativeFileName;
  318. PCTSTR fileNamePtr;
  319. PCTSTR testFileName;
  320. HANDLE fileHandle;
  321. WIN32_FIND_DATA fileInfo;
  322. BOOL result = FALSE;
  323. nativeFileName = IsmGetNativeObjectName (ObjectTypeId, ObjectName);
  324. if (nativeFileName) {
  325. fileNamePtr = GetFileNameFromPath (nativeFileName);
  326. if (fileNamePtr) {
  327. testFileName = JoinPaths (TempDir, fileNamePtr);
  328. fileHandle = BfCreateFile (testFileName);
  329. if (fileHandle) {
  330. CloseHandle (fileHandle);
  331. if (DoesFileExistEx (testFileName, &fileInfo)) {
  332. result = (fileInfo.cAlternateFileName [0] == 0) ||
  333. StringIMatch (fileInfo.cFileName, fileInfo.cAlternateFileName);
  334. }
  335. DeleteFile (testFileName);
  336. }
  337. }
  338. IsmReleaseMemory (nativeFileName);
  339. }
  340. return result;
  341. }
  342. BOOL
  343. WINAPI
  344. InfTransTransportSaveState (
  345. VOID
  346. )
  347. {
  348. MIG_OBJECTTYPEID objectTypeId;
  349. MIG_OBJECT_ENUM objEnum;
  350. MIG_OBJECTSTRINGHANDLE objectPattern = NULL;
  351. MIG_OBJECTSTRINGHANDLE objectName = NULL;
  352. MIG_CONTENT objectContent;
  353. PCTSTR infFile = NULL;
  354. HANDLE infFileHandle = NULL;
  355. PCTSTR objMultiSz;
  356. MULTISZ_ENUM multiSzEnum;
  357. BOOL firstMultiSz;
  358. PCTSTR fileName;
  359. PCTSTR dirName;
  360. DWORD status;
  361. MIG_OBJECTTYPEID dataTypeId;
  362. MIG_OBJECTTYPEID fileTypeId;
  363. TCHAR tempDir [MAX_PATH] = TEXT("");
  364. BOOL firstPass = TRUE;
  365. BOOL process = TRUE;
  366. #ifdef DEBUG
  367. PCTSTR nativeObjectName;
  368. #endif
  369. INT_PTR appReply;
  370. BOOL okSave = FALSE;
  371. TRANSCOPY_ERROR transCopyError;
  372. PTSTR encodedString = NULL;
  373. BOOL result = FALSE;
  374. GROWBUFFER writeBuffer = INIT_GROWBUFFER;
  375. if (DoesFileExist (g_InfTransTransportPath)) {
  376. status = pGetInfTransStatus (g_InfTransTransportStatus);
  377. switch (status) {
  378. case TRSTATUS_LOCKED:
  379. SetLastError (ERROR_ACCESS_DENIED);
  380. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, g_InfTransTransportPath));
  381. return FALSE;
  382. case TRSTATUS_DIRTY:
  383. result = FiRemoveAllFilesInTree (g_InfTransTransportPath);
  384. if (!result) {
  385. PushError ();
  386. SetLastError (ERROR_ACCESS_DENIED);
  387. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, g_InfTransTransportPath));
  388. PopError ();
  389. return FALSE;
  390. }
  391. break;
  392. case TRSTATUS_READY:
  393. default:
  394. if (IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_EXISTS, 0)) {
  395. result = FiRemoveAllFilesInTree (g_InfTransTransportPath);
  396. if (!result) {
  397. PushError ();
  398. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_EMPTY_DIR , g_InfTransTransportPath));
  399. PopError ();
  400. return FALSE;
  401. }
  402. } else {
  403. LOG ((LOG_ERROR, (PCSTR) MSG_NOT_EMPTY, g_InfTransTransportPath));
  404. SetLastError (ERROR_ALREADY_EXISTS);
  405. return FALSE;
  406. }
  407. break;
  408. }
  409. }
  410. if (!BfCreateDirectory (g_InfTransTransportPath)) {
  411. PushError ();
  412. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_DIR, g_InfTransTransportPath));
  413. PopError ();
  414. return FALSE;
  415. }
  416. g_InfTransTransportStatusHandle = BfCreateFile (g_InfTransTransportStatus);
  417. if (!g_InfTransTransportStatusHandle) {
  418. PushError ();
  419. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_STATUS_FILE, g_InfTransTransportStatus));
  420. PopError ();
  421. return FALSE;
  422. }
  423. pSetInfTransStatus (g_InfTransTransportStatusHandle, TRSTATUS_DIRTY);
  424. __try {
  425. IsmGetTempDirectory (tempDir, MAX_PATH);
  426. g_Platform = PLATFORM_SOURCE;
  427. objectName = IsmCreateObjectHandle (S_DATABASEFILE_LITE, NULL);
  428. if (IsmAcquireObjectEx (
  429. MIG_DATA_TYPE | PLATFORM_SOURCE,
  430. objectName,
  431. &objectContent,
  432. CONTENTTYPE_FILE,
  433. 0
  434. )) {
  435. // we have the database file, we assume it's an INF file
  436. // and we copy it to our transport location with the
  437. // migration.inf name.
  438. infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
  439. if (!CopyFile (objectContent.FileContent.ContentPath, infFile, FALSE)) {
  440. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_SAVE_ISM_INF));
  441. __leave;
  442. }
  443. IsmReleaseObject (&objectContent);
  444. } else {
  445. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
  446. __leave;
  447. }
  448. infFileHandle = BfOpenFile (infFile);
  449. if (!infFileHandle) {
  450. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
  451. __leave;
  452. }
  453. BfGoToEndOfFile (infFileHandle, 0);
  454. objectPattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
  455. objectTypeId = IsmGetFirstObjectTypeId ();
  456. dataTypeId = MIG_DATA_TYPE;
  457. fileTypeId = MIG_FILE_TYPE;
  458. while (objectTypeId) {
  459. if (firstPass) {
  460. WriteFileString (infFileHandle, TEXT("["));
  461. WriteFileString (infFileHandle, IsmGetObjectTypeName (objectTypeId));
  462. WriteFileString (infFileHandle, TEXT("]\r\n"));
  463. }
  464. if (IsmEnumFirstSourceObjectEx (&objEnum, objectTypeId, objectPattern, TRUE)) {
  465. do {
  466. writeBuffer.End = 0;
  467. if (IsmCheckCancel()) {
  468. IsmAbortObjectEnum (&objEnum);
  469. __leave;
  470. }
  471. if (objectTypeId == dataTypeId && StringIMatch(objEnum.ObjectName, objectName)) {
  472. continue;
  473. }
  474. if (IsmIsPersistentObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  475. process = TRUE;
  476. if (objectTypeId == fileTypeId) {
  477. if (firstPass) {
  478. process = pIsShortFileName (objectTypeId, objEnum.ObjectName, tempDir);
  479. } else {
  480. process = !pIsShortFileName (objectTypeId, objEnum.ObjectName, tempDir);
  481. }
  482. }
  483. if (process) {
  484. #ifdef DEBUG
  485. nativeObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  486. DEBUGMSG ((DBG_INFTRANS, "Transporting: %s", nativeObjectName));
  487. IsmReleaseMemory (nativeObjectName);
  488. #endif
  489. okSave = FALSE;
  490. while (!okSave) {
  491. if (!IsmAcquireObjectEx (
  492. objEnum.ObjectTypeId,
  493. objEnum.ObjectName,
  494. &objectContent,
  495. CONTENTTYPE_ANY,
  496. 0
  497. )) {
  498. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  499. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  500. transCopyError.Error = GetLastError ();
  501. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  502. appReply = APPRESPONSE_IGNORE;
  503. } else {
  504. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  505. if ((appReply == APPRESPONSE_NONE) ||
  506. (appReply == APPRESPONSE_FAIL)
  507. ) {
  508. IsmAbortObjectEnum (&objEnum);
  509. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  510. IsmReleaseMemory (transCopyError.ObjectName);
  511. IsmAbortObjectEnum (&objEnum);
  512. __leave;
  513. }
  514. }
  515. if (appReply == APPRESPONSE_IGNORE) {
  516. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  517. IsmReleaseMemory (transCopyError.ObjectName);
  518. break;
  519. }
  520. IsmReleaseMemory (transCopyError.ObjectName);
  521. continue;
  522. }
  523. okSave = TRUE;
  524. }
  525. if (okSave) {
  526. // we have an object let's write it to the migration.inf
  527. objMultiSz = IsmConvertObjectToMultiSz (
  528. objEnum.ObjectName,
  529. &objectContent
  530. );
  531. if (objMultiSz) {
  532. if (EnumFirstMultiSz (&multiSzEnum, objMultiSz)) {
  533. firstMultiSz = TRUE;
  534. do {
  535. if (firstMultiSz) {
  536. firstMultiSz = FALSE;
  537. } else {
  538. GbAppendString (&writeBuffer, TEXT(","));
  539. }
  540. encodedString = AllocPathString (SizeOfString (multiSzEnum.CurrentString) * 6);
  541. if (EncodeRuleCharsEx (encodedString, multiSzEnum.CurrentString, TEXT("~\r\n")) != NULL) {
  542. GbAppendString (&writeBuffer, encodedString);
  543. } else {
  544. GbAppendString (&writeBuffer, multiSzEnum.CurrentString);
  545. }
  546. FreePathString (encodedString);
  547. } while (EnumNextMultiSz (&multiSzEnum));
  548. GbAppendString (&writeBuffer, TEXT("\r\n"));
  549. }
  550. IsmReleaseMemory (objMultiSz);
  551. if (objectContent.ContentInFile) {
  552. if (objectContent.FileContent.ContentPath) {
  553. // transform the object name into a file name and copy the
  554. // content file there
  555. if (!pObjectNameToFileName (objEnum.ObjectName, &fileName, &dirName)) {
  556. LOG ((
  557. LOG_ERROR,
  558. (PCSTR) MSG_COPYFILE_FAILURE,
  559. objectContent.FileContent.ContentPath,
  560. fileName
  561. ));
  562. IsmAbortObjectEnum (&objEnum);
  563. __leave;
  564. }
  565. if (!BfCreateDirectory (dirName)) {
  566. LOG ((
  567. LOG_ERROR,
  568. (PCSTR) MSG_CREATE_FAILURE,
  569. dirName,
  570. objectContent.FileContent.ContentPath
  571. ));
  572. IsmAbortObjectEnum (&objEnum);
  573. __leave;
  574. }
  575. okSave = FALSE;
  576. while (!okSave) {
  577. if (!CopyFile (objectContent.FileContent.ContentPath, fileName, TRUE)) {
  578. transCopyError.ObjectType = IsmGetObjectTypeName (objEnum.ObjectTypeId);
  579. transCopyError.ObjectName = IsmGetNativeObjectName (objEnum.ObjectTypeId, objEnum.ObjectName);
  580. transCopyError.Error = GetLastError ();
  581. if (IsmIsNonCriticalObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  582. appReply = APPRESPONSE_IGNORE;
  583. } else {
  584. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  585. if ((appReply == APPRESPONSE_NONE) ||
  586. (appReply == APPRESPONSE_FAIL)
  587. ) {
  588. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  589. IsmReleaseMemory (transCopyError.ObjectName);
  590. IsmAbortObjectEnum (&objEnum);
  591. __leave;
  592. }
  593. }
  594. if (appReply == APPRESPONSE_IGNORE) {
  595. LOG ((LOG_WARNING, (PCSTR) MSG_IGNORE_COPYSOURCE, transCopyError.ObjectName));
  596. IsmReleaseMemory (transCopyError.ObjectName);
  597. break;
  598. }
  599. IsmReleaseMemory (transCopyError.ObjectName);
  600. continue;
  601. }
  602. okSave = TRUE;
  603. }
  604. if (dirName != fileName) {
  605. FreePathString (dirName);
  606. }
  607. FreePathString (fileName);
  608. }
  609. }
  610. } else {
  611. GbAppendString (&writeBuffer, TEXT("\r\n"));
  612. }
  613. IsmReleaseObject (&objectContent);
  614. }
  615. WriteFileString (infFileHandle, (PTSTR) writeBuffer.Buf);
  616. }
  617. }
  618. } while (IsmEnumNextObject (&objEnum));
  619. }
  620. if (!firstPass || objectTypeId != fileTypeId) {
  621. WriteFileString (infFileHandle, TEXT("\r\n\r\n"));
  622. }
  623. if ((objectTypeId == fileTypeId) && firstPass) {
  624. firstPass = FALSE;
  625. } else {
  626. objectTypeId = IsmGetNextObjectTypeId (objectTypeId);
  627. firstPass = TRUE;
  628. }
  629. }
  630. result = TRUE;
  631. }
  632. __finally {
  633. if (tempDir [0]) {
  634. FiRemoveAllFilesInTree (tempDir);
  635. }
  636. IsmDestroyObjectHandle (objectName);
  637. if (infFileHandle != NULL) {
  638. CloseHandle (infFileHandle);
  639. }
  640. IsmDestroyObjectHandle (objectPattern);
  641. FreePathString (infFile);
  642. INVALID_POINTER (infFile);
  643. }
  644. if (result) {
  645. pSetInfTransStatus (g_InfTransTransportStatusHandle, TRSTATUS_READY);
  646. }
  647. CloseHandle (g_InfTransTransportStatusHandle);
  648. g_InfTransTransportStatusHandle = NULL;
  649. GbFree (&writeBuffer);
  650. if (!result) {
  651. FiRemoveAllFilesInTree (g_InfTransTransportPath);
  652. }
  653. return result;
  654. }
  655. BOOL
  656. pSaveObjectContent (
  657. IN MIG_OBJECTTYPEID ObjectTypeId,
  658. IN PCTSTR ObjectName,
  659. IN PCTSTR DecoratedObject,
  660. IN PMIG_CONTENT ObjectContent
  661. )
  662. {
  663. PCTSTR fileName;
  664. BOOL result = FALSE;
  665. if (ObjectContent->ContentInFile) {
  666. MemDbSetValue (DecoratedObject, TRFLAG_FILE);
  667. if (pObjectNameToFileName (ObjectName, &fileName, NULL)) {
  668. if (DoesFileExist (fileName)) {
  669. MemDbAddSingleLinkage (DecoratedObject, fileName, 0);
  670. }
  671. FreePathString (fileName);
  672. }
  673. } else {
  674. MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
  675. if (ObjectContent->MemoryContent.ContentSize &&
  676. ObjectContent->MemoryContent.ContentBytes
  677. ) {
  678. MemDbSetUnorderedBlob (
  679. DecoratedObject,
  680. 0,
  681. ObjectContent->MemoryContent.ContentBytes,
  682. ObjectContent->MemoryContent.ContentSize
  683. );
  684. }
  685. }
  686. result = pInfTransSaveDetails (DecoratedObject, &(ObjectContent->Details));
  687. return result;
  688. }
  689. BOOL
  690. WINAPI
  691. InfTransTransportBeginApply (
  692. VOID
  693. )
  694. {
  695. PCTSTR infFile;
  696. HINF infHandle;
  697. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  698. MIG_OBJECTTYPEID objectTypeId;
  699. GROWBUFFER buff = INIT_GROWBUFFER;
  700. PCTSTR field;
  701. MIG_CONTENT objectContent;
  702. MIG_OBJECTSTRINGHANDLE objectName;
  703. UINT index;
  704. PCTSTR decoratedObject = NULL;
  705. DWORD status = 0;
  706. PTSTR decodedString = NULL;
  707. g_Platform = PLATFORM_DESTINATION;
  708. while (status != TRSTATUS_READY) {
  709. status = pGetInfTransStatus (g_InfTransTransportStatus);
  710. switch (status) {
  711. case TRSTATUS_LOCKED:
  712. if (!IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_LOCKED, 0)) {
  713. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY , g_InfTransTransportPath));
  714. SetLastError (ERROR_ACCESS_DENIED);
  715. return FALSE;
  716. }
  717. break;
  718. case TRSTATUS_DIRTY:
  719. SetLastError (ERROR_ACCESS_DENIED);
  720. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_InfTransTransportPath));
  721. return FALSE;
  722. case TRSTATUS_READY:
  723. break;
  724. default:
  725. SetLastError (ERROR_INVALID_DATA);
  726. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_InfTransTransportPath));
  727. return FALSE;
  728. }
  729. }
  730. g_InfTransTransportStatusHandle = BfOpenReadFile (g_InfTransTransportStatus);
  731. if (!g_InfTransTransportStatusHandle) {
  732. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_STATUS_FILE, g_InfTransTransportStatus));
  733. return FALSE;
  734. }
  735. infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
  736. // add the database file in memdb so we can serve AcquireObject from the ISM
  737. objectName = IsmCreateObjectHandle (S_DATABASEFILE_LITE, NULL);
  738. decoratedObject = pInfTransBuildDecoratedObject (MIG_DATA_TYPE | PLATFORM_SOURCE, objectName);
  739. MemDbSetValue (decoratedObject, TRFLAG_FILE);
  740. MemDbAddSingleLinkage (decoratedObject, infFile, 0);
  741. pInfTransDestroyDecoratedObject (decoratedObject);
  742. IsmDestroyObjectHandle (objectName);
  743. infHandle = InfOpenInfFile (infFile);
  744. if (infHandle == INVALID_HANDLE_VALUE) {
  745. SetLastError (ERROR_FILE_NOT_FOUND);
  746. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_ISM_INF, infFile));
  747. FreePathString (infFile);
  748. return FALSE;
  749. }
  750. objectTypeId = IsmGetFirstObjectTypeId ();
  751. while (objectTypeId) {
  752. if (InfFindFirstLine (infHandle, IsmGetObjectTypeName (objectTypeId), NULL, &is)) {
  753. do {
  754. index = 1;
  755. buff.End = 0;
  756. for (;;) {
  757. field = InfGetStringField (&is, index);
  758. if (!field) {
  759. break;
  760. }
  761. if (*field) {
  762. decodedString = DuplicatePathString (field, 0);
  763. if (DecodeRuleChars (decodedString, field) != NULL) {
  764. GbCopyString (&buff, decodedString);
  765. } else {
  766. GbCopyString (&buff, field);
  767. }
  768. FreePathString (decodedString);
  769. } else {
  770. GbCopyString (&buff, TEXT("<empty>"));
  771. }
  772. index ++;
  773. }
  774. if (buff.End) {
  775. GbCopyString (&buff, TEXT(""));
  776. if (IsmConvertMultiSzToObject (
  777. objectTypeId,
  778. (PCTSTR)buff.Buf,
  779. &objectName,
  780. &objectContent
  781. )) {
  782. // now save the object data into our database
  783. // for future reference
  784. decoratedObject = pInfTransBuildDecoratedObject (objectTypeId | PLATFORM_SOURCE, objectName);
  785. pSaveObjectContent (objectTypeId | g_Platform, objectName, decoratedObject, &objectContent);
  786. pInfTransDestroyDecoratedObject (decoratedObject);
  787. IsmDestroyObjectHandle (objectName);
  788. if ((objectContent.Details.DetailsSize) &&
  789. (objectContent.Details.DetailsData)
  790. ) {
  791. IsmReleaseMemory (objectContent.Details.DetailsData);
  792. }
  793. if (objectContent.ContentInFile) {
  794. if (objectContent.FileContent.ContentPath) {
  795. IsmReleaseMemory (objectContent.FileContent.ContentPath);
  796. }
  797. } else {
  798. if ((objectContent.MemoryContent.ContentSize) &&
  799. (objectContent.MemoryContent.ContentBytes)
  800. ) {
  801. IsmReleaseMemory (objectContent.MemoryContent.ContentBytes);
  802. }
  803. }
  804. }
  805. }
  806. } while (InfFindNextLine (&is));
  807. }
  808. objectTypeId = IsmGetNextObjectTypeId (objectTypeId);
  809. }
  810. GbFree (&buff);
  811. InfCleanUpInfStruct (&is);
  812. InfCloseInfFile (infHandle);
  813. FreePathString (infFile);
  814. return TRUE;
  815. }
  816. VOID
  817. WINAPI
  818. InfTransTransportEndApply (
  819. VOID
  820. )
  821. {
  822. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  823. CloseHandle (g_InfTransTransportStatusHandle);
  824. g_InfTransTransportStatusHandle = NULL;
  825. }
  826. VOID
  827. WINAPI
  828. InfTransTransportTerminate (
  829. VOID
  830. )
  831. {
  832. if (g_InfTransTransportPath) {
  833. FreePathString (g_InfTransTransportPath);
  834. g_InfTransTransportPath = NULL;
  835. }
  836. if (g_InfTransTransportStatus) {
  837. FreePathString (g_InfTransTransportStatus);
  838. g_InfTransTransportStatus = NULL;
  839. }
  840. }
  841. BOOL
  842. WINAPI
  843. InfTransTransportAcquireObject (
  844. IN MIG_OBJECTTYPEID ObjectTypeId,
  845. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  846. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  847. IN MIG_CONTENTTYPE ContentType,
  848. IN UINT MemoryContentLimit
  849. )
  850. {
  851. UINT value;
  852. PCBYTE memValue;
  853. UINT memValueSize;
  854. PCTSTR fileValue = NULL;
  855. BOOL valueInFile;
  856. KEYHANDLE keyHandle;
  857. PALLOCSTATE allocState;
  858. PCTSTR detailsKey = NULL;
  859. PBYTE details;
  860. UINT detailsSize;
  861. PCTSTR decoratedObject = NULL;
  862. HANDLE fileHandle;
  863. BOOL result = FALSE;
  864. if (!ObjectContent) {
  865. return FALSE;
  866. }
  867. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  868. MYASSERT ((ObjectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE);
  869. decoratedObject = pInfTransBuildDecoratedObject (ObjectTypeId, ObjectName);
  870. allocState = (PALLOCSTATE) MemAllocZeroed (sizeof (ALLOCSTATE));
  871. if (MemDbGetValue (decoratedObject, &value)) {
  872. if (value == TRFLAG_FILE) {
  873. valueInFile = TRUE;
  874. keyHandle = MemDbGetSingleLinkage (decoratedObject, 0, 0);
  875. if (keyHandle) {
  876. fileValue = MemDbGetKeyFromHandle (keyHandle, 0);
  877. result = fileValue != NULL;
  878. } else {
  879. fileValue = NULL;
  880. result = TRUE;
  881. }
  882. } else if (value == TRFLAG_MEMORY) {
  883. valueInFile = FALSE;
  884. memValueSize = 0;
  885. memValue = MemDbGetUnorderedBlob (decoratedObject, 0, &memValueSize);
  886. result = TRUE;
  887. } else {
  888. LOG ((LOG_ERROR, (PCSTR) MSG_UNSUPPORTED_DATA, value));
  889. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  890. }
  891. if (result) {
  892. result = FALSE;
  893. if (valueInFile) {
  894. if ((ContentType == CONTENTTYPE_ANY) ||
  895. (ContentType == CONTENTTYPE_FILE) ||
  896. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  897. ) {
  898. // this is stored as a file and it's wanted as a file
  899. ObjectContent->ObjectTypeId = ObjectTypeId;
  900. ObjectContent->ContentInFile = TRUE;
  901. if (fileValue) {
  902. ObjectContent->FileContent.ContentPath = DuplicatePathString (fileValue, 0);
  903. ObjectContent->FileContent.ContentSize = BfGetFileSize (ObjectContent->FileContent.ContentPath);
  904. } else {
  905. ObjectContent->FileContent.ContentSize = 0;
  906. ObjectContent->FileContent.ContentPath = NULL;
  907. }
  908. result = TRUE;
  909. } else {
  910. // this is stored as a file and it's wanted as memory
  911. ObjectContent->ObjectTypeId = ObjectTypeId;
  912. ObjectContent->ContentInFile = FALSE;
  913. if (fileValue) {
  914. ObjectContent->MemoryContent.ContentSize = (UINT) BfGetFileSize (fileValue);
  915. ObjectContent->MemoryContent.ContentBytes = MapFileIntoMemory (
  916. fileValue,
  917. &allocState->FileHandle,
  918. &allocState->MapHandle
  919. );
  920. result = (ObjectContent->MemoryContent.ContentBytes != NULL);
  921. } else {
  922. ObjectContent->MemoryContent.ContentSize = 0;
  923. ObjectContent->MemoryContent.ContentBytes = NULL;
  924. result = TRUE;
  925. }
  926. }
  927. MemDbReleaseMemory (fileValue);
  928. } else {
  929. if ((ContentType == CONTENTTYPE_ANY) ||
  930. (ContentType == CONTENTTYPE_MEMORY) ||
  931. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  932. ) {
  933. // this is stored as memory and it's wanted as memory
  934. ObjectContent->ObjectTypeId = ObjectTypeId;
  935. ObjectContent->ContentInFile = FALSE;
  936. ObjectContent->MemoryContent.ContentSize = memValueSize;
  937. ObjectContent->MemoryContent.ContentBytes = memValue;
  938. result = TRUE;
  939. } else {
  940. // this is stored as memory and it's wanted as a file
  941. if (memValue) {
  942. if (IsmGetTempFile (allocState->TempFile, ARRAYSIZE(allocState->TempFile))) {
  943. fileHandle = BfCreateFile (allocState->TempFile);
  944. if (fileHandle) {
  945. if (BfWriteFile (fileHandle, memValue, memValueSize)) {
  946. ObjectContent->ObjectTypeId = ObjectTypeId;
  947. ObjectContent->ContentInFile = TRUE;
  948. ObjectContent->FileContent.ContentSize = memValueSize;
  949. ObjectContent->FileContent.ContentPath = DuplicatePathString (allocState->TempFile, 0);
  950. result = TRUE;
  951. }
  952. CloseHandle (fileHandle);
  953. }
  954. }
  955. MemDbReleaseMemory (memValue);
  956. } else {
  957. ObjectContent->ObjectTypeId = ObjectTypeId;
  958. ObjectContent->ContentInFile = TRUE;
  959. ObjectContent->FileContent.ContentSize = 0;
  960. ObjectContent->FileContent.ContentPath = NULL;
  961. }
  962. }
  963. }
  964. }
  965. } else {
  966. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  967. }
  968. if (result) {
  969. //
  970. // Fill the details
  971. //
  972. detailsKey = JoinText (S_DETAILS_PREFIX, decoratedObject);
  973. details = MemDbGetUnorderedBlob (detailsKey, 0, &detailsSize);
  974. if (!details) {
  975. detailsSize = 0;
  976. }
  977. allocState->DetailsPtr = details;
  978. ObjectContent->Details.DetailsSize = detailsSize;
  979. ObjectContent->Details.DetailsData = details;
  980. FreeText (detailsKey);
  981. ObjectContent->TransHandle = allocState;
  982. }
  983. if (!result) {
  984. FreeAlloc (allocState);
  985. }
  986. FreePathString (decoratedObject);
  987. return result;
  988. }
  989. BOOL
  990. WINAPI
  991. InfTransTransportReleaseObject (
  992. IN OUT PMIG_CONTENT ObjectContent
  993. )
  994. {
  995. PALLOCSTATE allocState;
  996. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  997. allocState = (PALLOCSTATE) ObjectContent->TransHandle;
  998. if (ObjectContent->ContentInFile) {
  999. FreePathString (ObjectContent->FileContent.ContentPath);
  1000. if (allocState && allocState->TempFile[0]) {
  1001. DeleteFile (allocState->TempFile);
  1002. }
  1003. } else {
  1004. if (allocState && allocState->FileHandle && allocState->MapHandle) {
  1005. UnmapFile (
  1006. ObjectContent->MemoryContent.ContentBytes,
  1007. allocState->MapHandle,
  1008. allocState->FileHandle
  1009. );
  1010. } else {
  1011. MemDbReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1012. }
  1013. }
  1014. if (allocState && allocState->DetailsPtr) {
  1015. MemDbReleaseMemory (allocState->DetailsPtr);
  1016. }
  1017. FreeAlloc (allocState);
  1018. return TRUE;
  1019. }