Leaked source code of windows server 2003
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.

1688 lines
58 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. #include <conio.h>
  18. #define DBG_INFTRANS "InfTrans"
  19. //
  20. // Strings
  21. //
  22. #define S_TRANSPORT_DIR TEXT("USMT2I.UNC")
  23. #define S_TRANSPORT_DIR_E TEXT("USMT2E.UNC")
  24. #define S_TRANSPORT_INF_FILE TEXT("migration.inf")
  25. #define S_TRANSPORT_STATUS_FILE TEXT("status")
  26. #define S_TRANSPORT_ESTIMATE_FILE TEXT("USMTSIZE.TXT")
  27. #define S_DETAILS_PREFIX TEXT("details")
  28. #define S_DATABASEFILE_LITE TEXT("|MainDatabaseFile\\LITE") // pipe is to decorate for uniqueness
  29. //
  30. // Constants
  31. //
  32. #define TRFLAG_FILE 0x01
  33. #define TRFLAG_MEMORY 0x02
  34. #define INFTR_SIG 0x55534D32 //USM2
  35. #define TRSTATUS_DIRTY 0x00000001
  36. #define TRSTATUS_READY 0x00000002
  37. #define TRSTATUS_LOCKED 0x00000003
  38. //
  39. // Macros
  40. //
  41. // None
  42. //
  43. // Types
  44. //
  45. typedef struct {
  46. TCHAR TempFile [MAX_PATH];
  47. PCVOID AllocPtr;
  48. PCVOID DetailsPtr;
  49. HANDLE FileHandle;
  50. HANDLE MapHandle;
  51. } ALLOCSTATE, *PALLOCSTATE;
  52. typedef struct {
  53. UINT ClusterSize;
  54. ULONGLONG StoreSize;
  55. } ESTIMATE_SIZE, *PESTIMATE_SIZE;
  56. //
  57. // Globals
  58. //
  59. BOOL g_EstimateSizeOnly = FALSE;
  60. MIG_TRANSPORTSTORAGEID g_ReliableStorageId;
  61. PCTSTR g_InfTransStoragePath = NULL;
  62. PCTSTR g_InfTransTransportPath = NULL;
  63. PCTSTR g_InfTransTransportStatus = NULL;
  64. HANDLE g_InfTransTransportStatusHandle = NULL;
  65. UINT g_Platform;
  66. MIG_PROGRESSSLICEID g_DatabaseSlice;
  67. MIG_PROGRESSSLICEID g_PersistentSlice;
  68. ESTIMATE_SIZE g_EstimateSize [] =
  69. {
  70. {512, 0},
  71. {1024, 0},
  72. {2048, 0},
  73. {4096, 0},
  74. {8192, 0},
  75. {16384, 0},
  76. {32768, 0},
  77. {65536, 0},
  78. {131072, 0},
  79. {262144, 0},
  80. {524288, 0},
  81. {1048576, 0},
  82. {0, 0}
  83. };
  84. //
  85. // Macro expansion list
  86. //
  87. // None
  88. //
  89. // Private function prototypes
  90. //
  91. // see unctrans.h
  92. //
  93. // Macro expansion definition
  94. //
  95. // None
  96. //
  97. // Code
  98. //
  99. BOOL
  100. pSetInfTransStatus (
  101. IN HANDLE TrJournalHandle,
  102. IN DWORD Status
  103. )
  104. {
  105. DWORD signature = INFTR_SIG;
  106. BOOL result = FALSE;
  107. if (BfSetFilePointer (TrJournalHandle, 0)) {
  108. result = TRUE;
  109. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&signature), sizeof (DWORD));
  110. result = result && BfWriteFile (TrJournalHandle, (PBYTE)(&Status), sizeof (DWORD));
  111. result = result && FlushFileBuffers (TrJournalHandle);
  112. }
  113. return TRUE;
  114. }
  115. DWORD
  116. pGetInfTransStatus (
  117. IN PCTSTR TrJournal
  118. )
  119. {
  120. HANDLE trJrnHandle;
  121. DWORD signature = 0;
  122. DWORD error;
  123. DWORD result = 0;
  124. if (TrJournal && TrJournal [0]) {
  125. trJrnHandle = BfOpenReadFile (TrJournal);
  126. if (trJrnHandle) {
  127. if (BfSetFilePointer (trJrnHandle, 0)) {
  128. if (BfReadFile (trJrnHandle, (PBYTE)(&signature), sizeof (DWORD))) {
  129. if (signature == INFTR_SIG) {
  130. if (!BfReadFile (trJrnHandle, (PBYTE)(&result), sizeof (DWORD))) {
  131. result = 0;
  132. }
  133. }
  134. }
  135. }
  136. CloseHandle (trJrnHandle);
  137. } else {
  138. error = GetLastError ();
  139. if ((error == ERROR_ACCESS_DENIED) ||
  140. (error == ERROR_SHARING_VIOLATION)
  141. ) {
  142. result = TRSTATUS_LOCKED;
  143. }
  144. }
  145. }
  146. return result;
  147. }
  148. BOOL
  149. WINAPI
  150. InfTransTransportInitialize (
  151. IN PMIG_LOGCALLBACK LogCallback
  152. )
  153. {
  154. //
  155. // Initialize globals
  156. //
  157. LogReInit (NULL, NULL, NULL, (PLOGCALLBACK) LogCallback);
  158. g_ReliableStorageId = IsmRegisterTransport (S_RELIABLE_STORAGE_TRANSPORT);
  159. return TRUE;
  160. }
  161. VOID
  162. WINAPI
  163. InfTransTransportEstimateProgressBar (
  164. MIG_PLATFORMTYPEID PlatformTypeId
  165. )
  166. {
  167. DEBUGMSG ((DBG_VERBOSE, "Assuming transport download has no progress impact"));
  168. }
  169. BOOL
  170. WINAPI
  171. InfTransTransportQueryCapabilities (
  172. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  173. OUT PMIG_TRANSPORTTYPE TransportType,
  174. OUT PMIG_TRANSPORTCAPABILITIES Capabilities,
  175. OUT PCTSTR *FriendlyDescription
  176. )
  177. {
  178. if (TransportStorageId != g_ReliableStorageId) {
  179. return FALSE;
  180. }
  181. *TransportType = TRANSPORTTYPE_LIGHT;
  182. *Capabilities = CAPABILITY_SPACEESTIMATE;
  183. *FriendlyDescription = TEXT("Another Computer on the Network");
  184. return TRUE;
  185. }
  186. BOOL
  187. WINAPI
  188. InfTransTransportSetStorage (
  189. IN MIG_PLATFORMTYPEID Platform,
  190. IN MIG_TRANSPORTSTORAGEID TransportStorageId,
  191. IN MIG_TRANSPORTCAPABILITIES RequiredCapabilities,
  192. IN PCTSTR StoragePath,
  193. OUT PBOOL Valid,
  194. OUT PBOOL ImageExists
  195. )
  196. {
  197. PCTSTR transportPath;
  198. PCTSTR transportStatus;
  199. MIG_OBJECTSTRINGHANDLE encodedPath;
  200. DWORD status;
  201. BOOL result = FALSE;
  202. if (Valid) {
  203. *Valid = FALSE;
  204. }
  205. if (ImageExists) {
  206. *ImageExists = FALSE;
  207. }
  208. if (TransportStorageId == g_ReliableStorageId) {
  209. if (!RequiredCapabilities ||
  210. (RequiredCapabilities & CAPABILITY_SPACEESTIMATE)
  211. ) {
  212. if (RequiredCapabilities & CAPABILITY_SPACEESTIMATE) {
  213. g_EstimateSizeOnly = TRUE;
  214. }
  215. if (g_EstimateSizeOnly) {
  216. transportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR_E);
  217. } else {
  218. transportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
  219. }
  220. transportStatus = JoinPaths (transportPath, S_TRANSPORT_STATUS_FILE);
  221. if (!DoesFileExist (transportPath)) {
  222. // we require UNC path or a full path (like c:\...)
  223. if (transportPath[0] == '\\' && transportPath[1] == '\\') {
  224. // this is a UNC path
  225. *Valid = TRUE;
  226. } else if (transportPath[1] == ':') {
  227. // this is a normal full path
  228. *Valid = TRUE;
  229. } else {
  230. *Valid = FALSE;
  231. }
  232. *ImageExists = FALSE;
  233. } else {
  234. status = pGetInfTransStatus (transportStatus);
  235. switch (status) {
  236. case TRSTATUS_LOCKED:
  237. *ImageExists = TRUE;
  238. *Valid = FALSE;
  239. break;
  240. case TRSTATUS_READY:
  241. *ImageExists = TRUE;
  242. *Valid = TRUE;
  243. break;
  244. case TRSTATUS_DIRTY:
  245. *ImageExists = FALSE;
  246. *Valid = TRUE;
  247. break;
  248. default:
  249. *ImageExists = FALSE;
  250. *Valid = TRUE;
  251. }
  252. }
  253. FreePathString (transportStatus);
  254. FreePathString (transportPath);
  255. result = TRUE;
  256. }
  257. }
  258. if (result && *Valid) {
  259. if (g_InfTransStoragePath) {
  260. FreePathString (g_InfTransStoragePath);
  261. g_InfTransStoragePath = NULL;
  262. }
  263. if (g_InfTransTransportPath) {
  264. FreePathString (g_InfTransTransportPath);
  265. g_InfTransTransportPath = NULL;
  266. }
  267. g_InfTransStoragePath = DuplicatePathString (StoragePath, 0);
  268. if (g_EstimateSizeOnly) {
  269. g_InfTransTransportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR_E);
  270. } else {
  271. g_InfTransTransportPath = JoinPaths (StoragePath, S_TRANSPORT_DIR);
  272. }
  273. g_InfTransTransportStatus = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_STATUS_FILE);
  274. encodedPath = IsmCreateSimpleObjectPattern (g_InfTransTransportPath, FALSE, NULL, FALSE);
  275. if (encodedPath) {
  276. IsmRegisterStaticExclusion (MIG_FILE_TYPE, encodedPath);
  277. IsmDestroyObjectHandle (encodedPath);
  278. }
  279. }
  280. return result;
  281. }
  282. BOOL
  283. pInfTransSaveDetails (
  284. IN PCTSTR DecoratedObject,
  285. IN PMIG_DETAILS Details
  286. )
  287. {
  288. PCTSTR key;
  289. BOOL b;
  290. if ((!Details) || (!Details->DetailsSize)) {
  291. return TRUE;
  292. }
  293. key = JoinText (S_DETAILS_PREFIX, DecoratedObject);
  294. b = (MemDbSetUnorderedBlob (key, 0, Details->DetailsData, Details->DetailsSize) != 0);
  295. FreeText (key);
  296. return b;
  297. }
  298. PCTSTR
  299. pInfTransBuildDecoratedObject (
  300. IN MIG_OBJECTTYPEID ObjectTypeId,
  301. IN ENCODEDSTRHANDLE ObjectName
  302. )
  303. {
  304. TCHAR prefix[32];
  305. wsprintf (prefix, TEXT("%u"), ObjectTypeId & (~PLATFORM_MASK));
  306. return JoinPaths (prefix, ObjectName);
  307. }
  308. VOID
  309. pInfTransDestroyDecoratedObject (
  310. IN PCTSTR String
  311. )
  312. {
  313. FreePathString (String);
  314. }
  315. BOOL
  316. pObjectNameToFileName (
  317. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  318. OUT PCTSTR *FileName,
  319. OUT PCTSTR *DirName OPTIONAL
  320. )
  321. {
  322. PCTSTR node, leaf;
  323. PCTSTR newNode, dirName;
  324. BOOL result = FALSE;
  325. if (IsmCreateObjectStringsFromHandle (ObjectName, &node, &leaf)) {
  326. newNode = StringSearchAndReplace (node, TEXT(":"), TEXT(""));
  327. if (newNode) {
  328. result = TRUE;
  329. if (leaf) {
  330. dirName = JoinPaths (g_InfTransTransportPath, newNode);
  331. *FileName = JoinPaths (dirName, leaf);
  332. if (!DirName) {
  333. FreePathString (dirName);
  334. } else {
  335. *DirName = dirName;
  336. }
  337. FreePathString (newNode);
  338. } else {
  339. *FileName = JoinPaths (g_InfTransTransportPath, newNode);
  340. if (DirName) {
  341. *DirName = *FileName;
  342. }
  343. FreePathString (newNode);
  344. }
  345. } else {
  346. dirName = JoinPaths (g_InfTransTransportPath, node);
  347. *FileName = JoinPaths (dirName, leaf);
  348. FreePathString (dirName);
  349. if (DirName) {
  350. *DirName = JoinPaths (g_InfTransTransportPath, node);
  351. }
  352. result = TRUE;
  353. }
  354. IsmDestroyObjectString (node);
  355. IsmDestroyObjectString (leaf);
  356. }
  357. return result;
  358. }
  359. BOOL
  360. pIsShortFileName (
  361. IN MIG_OBJECTTYPEID ObjectTypeId,
  362. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  363. IN PCTSTR TempDir
  364. )
  365. {
  366. PCTSTR nativeFileName;
  367. PCTSTR fileNamePtr;
  368. PCTSTR testFileName;
  369. HANDLE fileHandle;
  370. WIN32_FIND_DATA fileInfo;
  371. BOOL result = FALSE;
  372. nativeFileName = IsmGetNativeObjectName (ObjectTypeId, ObjectName);
  373. if (nativeFileName) {
  374. fileNamePtr = GetFileNameFromPath (nativeFileName);
  375. if (fileNamePtr) {
  376. testFileName = JoinPaths (TempDir, fileNamePtr);
  377. fileHandle = BfCreateFile (testFileName);
  378. if (fileHandle) {
  379. CloseHandle (fileHandle);
  380. if (DoesFileExistEx (testFileName, &fileInfo)) {
  381. result = (fileInfo.cAlternateFileName [0] == 0) ||
  382. StringIMatch (fileInfo.cFileName, fileInfo.cAlternateFileName);
  383. }
  384. DeleteFile (testFileName);
  385. }
  386. }
  387. IsmReleaseMemory (nativeFileName);
  388. }
  389. return result;
  390. }
  391. UINT
  392. pGetClusterSize (
  393. IN PCTSTR Path
  394. )
  395. {
  396. PTSTR drivePath = NULL;
  397. PTSTR wackPtr;
  398. DWORD sectPerClust = 0;
  399. DWORD bytesPerSect = 0;
  400. DWORD freeClust = 0;
  401. DWORD totalClust = 0;
  402. UINT result = 0;
  403. DWORD err = 0;
  404. if (!Path) {
  405. return result;
  406. }
  407. // if this is a UNC drive
  408. if (Path [0] && (Path [0] == TEXT('\\')) && (Path [1] == TEXT('\\'))) {
  409. // we need to leave exactly 2 segments (like \\server\share) and
  410. // add a wack at the end
  411. drivePath = DuplicatePathString (Path, 1);
  412. // we know the first two characters are wacks. Wack is a single byte
  413. // character so the next call is safe
  414. wackPtr = _tcschr (drivePath + 2, TEXT('\\'));
  415. if (wackPtr) {
  416. wackPtr = _tcsinc (wackPtr);
  417. if (wackPtr) {
  418. wackPtr = _tcschr (wackPtr, TEXT('\\'));
  419. if (wackPtr) {
  420. // there are more than two segments here
  421. // wack is a single byte char so this is safe
  422. *wackPtr = 0;
  423. }
  424. AppendWack (drivePath);
  425. } else {
  426. // something is wrong, we could not advance one character?
  427. FreePathString (drivePath);
  428. drivePath = NULL;
  429. }
  430. } else {
  431. // something is wrong, we don't even have one segment
  432. FreePathString (drivePath);
  433. drivePath = NULL;
  434. }
  435. } else {
  436. if (Path [0] && (Path [1] == TEXT (':')) && (Path [2] == TEXT ('\\'))) {
  437. drivePath = DuplicatePathString (Path, 0);
  438. drivePath [3] = 0;
  439. }
  440. }
  441. if (drivePath) {
  442. if (GetDiskFreeSpace (drivePath, &sectPerClust, &bytesPerSect, &freeClust, &totalClust)) {
  443. result = bytesPerSect * sectPerClust;
  444. } else {
  445. LOG ((LOG_WARNING, (PCSTR) MSG_CLUSTER_SIZE_ERROR, GetLastError ()));
  446. }
  447. FreePathString (drivePath);
  448. drivePath = NULL;
  449. }
  450. return result;
  451. }
  452. BOOL
  453. pStoreStatusOK (
  454. IN PCTSTR StorePath,
  455. IN PCTSTR StoreStatusPath
  456. )
  457. {
  458. DWORD status;
  459. BOOL result = FALSE;
  460. if (DoesFileExist (StorePath)) {
  461. status = pGetInfTransStatus (StoreStatusPath);
  462. switch (status) {
  463. case TRSTATUS_LOCKED:
  464. SetLastError (ERROR_ACCESS_DENIED);
  465. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, StorePath));
  466. return FALSE;
  467. case TRSTATUS_DIRTY:
  468. result = FiRemoveAllFilesInTree (StorePath);
  469. if (!result) {
  470. PushError ();
  471. SetLastError (ERROR_ACCESS_DENIED);
  472. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY, StorePath));
  473. PopError ();
  474. return FALSE;
  475. }
  476. break;
  477. case TRSTATUS_READY:
  478. default:
  479. if (IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_EXISTS, 0)) {
  480. result = FiRemoveAllFilesInTree (StorePath);
  481. if (!result) {
  482. PushError ();
  483. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_EMPTY_DIR , StorePath));
  484. PopError ();
  485. return FALSE;
  486. }
  487. } else {
  488. SetLastError (ERROR_ALREADY_EXISTS);
  489. LOG ((LOG_ERROR, (PCSTR) MSG_NOT_EMPTY, StorePath));
  490. return FALSE;
  491. }
  492. break;
  493. }
  494. }
  495. if (!BfCreateDirectory (StorePath)) {
  496. PushError ();
  497. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_DIR, StorePath));
  498. PopError ();
  499. return FALSE;
  500. }
  501. g_InfTransTransportStatusHandle = BfCreateFile (StoreStatusPath);
  502. if (!g_InfTransTransportStatusHandle) {
  503. PushError ();
  504. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_STATUS_FILE, StoreStatusPath));
  505. PopError ();
  506. return FALSE;
  507. }
  508. pSetInfTransStatus (g_InfTransTransportStatusHandle, TRSTATUS_DIRTY);
  509. return TRUE;
  510. }
  511. BOOL
  512. pWriteEstimateFile (
  513. VOID
  514. )
  515. {
  516. PCTSTR infFile = NULL;
  517. HANDLE infFileHandle = NULL;
  518. PCTSTR estimateFile = NULL;
  519. HANDLE estimateFileHandle = NULL;
  520. UINT index = 0;
  521. LONGLONG fileSize = 0;
  522. UINT currClusterSize = 0;
  523. ULONGLONG currStoreSize = 0;
  524. TCHAR estimateBuff1 [MAX_PATH];
  525. TCHAR estimateBuff2 [MAX_PATH];
  526. BOOL result = TRUE;
  527. // now it's a good time to add all other files that we used to
  528. // the estimate, delete them and then write the estimate file
  529. // in the root of the transport directory (g_InfTransStoragePath)
  530. // let's add the status file to the estimate
  531. if (g_InfTransTransportStatus) {
  532. fileSize = BfGetFileSize (g_InfTransTransportStatus);
  533. if (fileSize) {
  534. index = 0;
  535. while (TRUE) {
  536. if (g_EstimateSize [index].ClusterSize == 0) {
  537. break;
  538. }
  539. g_EstimateSize [index].StoreSize +=
  540. ((fileSize / g_EstimateSize [index].ClusterSize) + 1) * g_EstimateSize [index].ClusterSize;
  541. index ++;
  542. }
  543. }
  544. }
  545. // OK, now let's add the migration.inf file to the estimate
  546. infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
  547. if (infFile) {
  548. fileSize = BfGetFileSize (infFile);
  549. if (fileSize) {
  550. index = 0;
  551. while (TRUE) {
  552. if (g_EstimateSize [index].ClusterSize == 0) {
  553. break;
  554. }
  555. g_EstimateSize [index].StoreSize +=
  556. ((fileSize / g_EstimateSize [index].ClusterSize) + 1) * g_EstimateSize [index].ClusterSize;
  557. index ++;
  558. }
  559. }
  560. FreePathString (infFile);
  561. infFile = NULL;
  562. } else {
  563. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
  564. result = FALSE;
  565. }
  566. if (result) {
  567. // Now, let's delete the USMT2E.UNC directory
  568. FiRemoveAllFilesInTree (g_InfTransTransportPath);
  569. // Finally, let's write the estimate file
  570. estimateFile = JoinPaths (g_InfTransStoragePath, S_TRANSPORT_ESTIMATE_FILE);
  571. if (estimateFile) {
  572. if (DoesFileExist (estimateFile)) {
  573. if (IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_EXISTS, 0)) {
  574. result = DeleteFile (estimateFile);
  575. } else {
  576. SetLastError (ERROR_ALREADY_EXISTS);
  577. LOG ((LOG_ERROR, (PCSTR) MSG_NOT_EMPTY, estimateFile));
  578. result = FALSE;
  579. }
  580. }
  581. if (result) {
  582. estimateFileHandle = BfCreateFile (estimateFile);
  583. if (estimateFileHandle && (estimateFileHandle != INVALID_HANDLE_VALUE)) {
  584. // finally, let's write the stuff
  585. // first write the requirement for current cluster size
  586. currClusterSize = pGetClusterSize (g_InfTransStoragePath);
  587. if (currClusterSize) {
  588. currStoreSize = 0;
  589. index = 0;
  590. while (TRUE) {
  591. if (g_EstimateSize [index].ClusterSize == 0) {
  592. break;
  593. }
  594. if (g_EstimateSize [index].ClusterSize == currClusterSize) {
  595. currStoreSize = g_EstimateSize [index].StoreSize;
  596. break;
  597. }
  598. index ++;
  599. }
  600. }
  601. _ui64tot (
  602. currStoreSize,
  603. estimateBuff2,
  604. 10
  605. );
  606. wsprintf (
  607. estimateBuff1,
  608. TEXT("%u\t%s\r\n"),
  609. currClusterSize,
  610. estimateBuff2
  611. );
  612. WriteFileString (estimateFileHandle, estimateBuff1);
  613. // then write all cluster sizes
  614. index = 0;
  615. while (TRUE) {
  616. if (g_EstimateSize [index].ClusterSize == 0) {
  617. break;
  618. }
  619. _ui64tot (
  620. g_EstimateSize [index].StoreSize,
  621. estimateBuff2,
  622. 10
  623. );
  624. wsprintf (
  625. estimateBuff1,
  626. TEXT("%u\t%s\r\n"),
  627. g_EstimateSize [index].ClusterSize,
  628. estimateBuff2
  629. );
  630. WriteFileString (estimateFileHandle, estimateBuff1);
  631. index ++;
  632. }
  633. CloseHandle (estimateFileHandle);
  634. } else {
  635. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_ESTIMATE_FILE));
  636. result = FALSE;
  637. }
  638. } else {
  639. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_ESTIMATE_FILE));
  640. }
  641. } else {
  642. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_CREATE_ESTIMATE_FILE));
  643. result = FALSE;
  644. }
  645. }
  646. return result;
  647. }
  648. BOOL
  649. pAddFileSize (
  650. IN PCTSTR FileName
  651. )
  652. {
  653. UINT index = 0;
  654. LONGLONG fileSize = 0;
  655. fileSize = BfGetFileSize (FileName);
  656. if (fileSize) {
  657. index = 0;
  658. while (TRUE) {
  659. if (g_EstimateSize [index].ClusterSize == 0) {
  660. break;
  661. }
  662. g_EstimateSize [index].StoreSize +=
  663. ((fileSize / g_EstimateSize [index].ClusterSize) + 1) * g_EstimateSize [index].ClusterSize;
  664. index ++;
  665. }
  666. }
  667. return TRUE;
  668. }
  669. BOOL
  670. pAddOneCluster (
  671. VOID
  672. )
  673. {
  674. UINT index = 0;
  675. LONGLONG fileSize = 0;
  676. index = 0;
  677. while (TRUE) {
  678. if (g_EstimateSize [index].ClusterSize == 0) {
  679. break;
  680. }
  681. g_EstimateSize [index].StoreSize += g_EstimateSize [index].ClusterSize;
  682. index ++;
  683. }
  684. return TRUE;
  685. }
  686. BOOL
  687. pSaveObject (
  688. IN MIG_OBJECTTYPEID ObjectTypeId,
  689. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  690. IN BOOL ForceNoncritical,
  691. IN OUT PGROWBUFFER Buffer
  692. )
  693. {
  694. MIG_CONTENT objectContent;
  695. TRANSCOPY_ERROR transCopyError;
  696. INT_PTR appReply;
  697. PCTSTR objMultiSz;
  698. MULTISZ_ENUM multiSzEnum;
  699. BOOL firstMultiSz;
  700. PTSTR encodedString = NULL;
  701. PCTSTR fileName;
  702. PCTSTR dirName;
  703. PCTSTR nativeObjectName;
  704. BOOL okSave = FALSE;
  705. BOOL forceLogError = FALSE;
  706. okSave = FALSE;
  707. while (!okSave) {
  708. if (!IsmAcquireObjectEx (
  709. ObjectTypeId,
  710. ObjectName,
  711. &objectContent,
  712. CONTENTTYPE_ANY,
  713. 0
  714. )) {
  715. transCopyError.ObjectType = IsmGetObjectTypeName (ObjectTypeId);
  716. transCopyError.ObjectName = IsmGetNativeObjectName (ObjectTypeId, ObjectName);
  717. transCopyError.Error = GetLastError ();
  718. if (ForceNoncritical || IsmIsNonCriticalObject (ObjectTypeId, ObjectName)) {
  719. appReply = APPRESPONSE_IGNORE;
  720. } else {
  721. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  722. if ((appReply == APPRESPONSE_NONE) ||
  723. (appReply == APPRESPONSE_FAIL)
  724. ) {
  725. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  726. IsmReleaseMemory (transCopyError.ObjectName);
  727. return FALSE;
  728. }
  729. }
  730. if (appReply == APPRESPONSE_IGNORE) {
  731. LOG ((
  732. LOG_WARNING,
  733. (PCSTR) MSG_IGNORE_COPYSOURCE,
  734. transCopyError.ObjectName,
  735. GetLastError (),
  736. GetLastError ()
  737. ));
  738. IsmReleaseMemory (transCopyError.ObjectName);
  739. break;
  740. }
  741. IsmReleaseMemory (transCopyError.ObjectName);
  742. continue;
  743. }
  744. okSave = TRUE;
  745. }
  746. if (okSave) {
  747. // we have an object let's write it to the migration.inf
  748. objMultiSz = IsmConvertObjectToMultiSz (
  749. ObjectName,
  750. &objectContent
  751. );
  752. if (objMultiSz) {
  753. if (EnumFirstMultiSz (&multiSzEnum, objMultiSz)) {
  754. firstMultiSz = TRUE;
  755. do {
  756. if (firstMultiSz) {
  757. firstMultiSz = FALSE;
  758. } else {
  759. GbAppendString (Buffer, TEXT(","));
  760. }
  761. encodedString = AllocPathString (SizeOfString (multiSzEnum.CurrentString) * 6);
  762. if (EncodeRuleCharsEx (encodedString, multiSzEnum.CurrentString, TEXT("~\r\n%")) != NULL) {
  763. GbAppendString (Buffer, encodedString);
  764. } else {
  765. GbAppendString (Buffer, multiSzEnum.CurrentString);
  766. }
  767. FreePathString (encodedString);
  768. } while (EnumNextMultiSz (&multiSzEnum));
  769. GbAppendString (Buffer, TEXT("\r\n"));
  770. }
  771. IsmReleaseMemory (objMultiSz);
  772. if (objectContent.ContentInFile) {
  773. if (objectContent.FileContent.ContentPath) {
  774. // Let's see if we only want to estimate the size
  775. if (g_EstimateSizeOnly) {
  776. if (pObjectNameToFileName (ObjectName, &fileName, &dirName)) {
  777. // let's add info about directory. The rule is: every new full
  778. // directory is considered to take one cluster
  779. if (!DoesFileExist (dirName)) {
  780. pAddOneCluster ();
  781. }
  782. if (dirName != fileName) {
  783. FreePathString (dirName);
  784. }
  785. FreePathString (fileName);
  786. }
  787. pAddFileSize (objectContent.FileContent.ContentPath);
  788. } else {
  789. // transform the object name into a file name and copy the
  790. // content file there
  791. if (!pObjectNameToFileName (ObjectName, &fileName, &dirName)) {
  792. SetLastError (ERROR_INVALID_DATA);
  793. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, objectContent.FileContent.ContentPath));
  794. return FALSE;
  795. }
  796. if (!BfCreateDirectory (dirName)) {
  797. LOG ((
  798. LOG_ERROR,
  799. (PCSTR) MSG_CREATE_FAILURE,
  800. dirName,
  801. objectContent.FileContent.ContentPath
  802. ));
  803. if (GetLastError () == ERROR_FILENAME_EXCED_RANGE) {
  804. // now we want to see if the app wants us to continue or just quit the transport
  805. transCopyError.ObjectType = IsmGetObjectTypeName (ObjectTypeId);
  806. transCopyError.ObjectName = dirName;
  807. transCopyError.Error = GetLastError ();
  808. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  809. if (appReply == APPRESPONSE_IGNORE) {
  810. return TRUE;
  811. }
  812. }
  813. return FALSE;
  814. }
  815. okSave = FALSE;
  816. while (!okSave) {
  817. if (!CopyFile (objectContent.FileContent.ContentPath, fileName, TRUE)) {
  818. if ((TcharCount (fileName) >= MAX_PATH) && (GetLastError () == ERROR_PATH_NOT_FOUND)) {
  819. // we tried to copy a file to a location that was bigger than MAX_PATH
  820. // Normally this should return the error 206 (ERROR_FILENAME_EXCED_RANGE).
  821. // However, in my tests this returns error 3 (ERROR_PATH_NOT_FOUND).
  822. // Let's just guard for this case:
  823. SetLastError (ERROR_FILENAME_EXCED_RANGE);
  824. }
  825. transCopyError.ObjectType = IsmGetObjectTypeName (ObjectTypeId);
  826. transCopyError.ObjectName = IsmGetNativeObjectName (ObjectTypeId, ObjectName);
  827. transCopyError.Error = GetLastError ();
  828. forceLogError = FALSE;
  829. if (ForceNoncritical || IsmIsNonCriticalObject (ObjectTypeId, ObjectName)) {
  830. appReply = APPRESPONSE_IGNORE;
  831. } else {
  832. appReply = IsmSendMessageToApp (TRANSPORTMESSAGE_SRC_COPY_ERROR, (ULONG_PTR)&transCopyError);
  833. if ((appReply == APPRESPONSE_NONE) ||
  834. (appReply == APPRESPONSE_FAIL)
  835. ) {
  836. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  837. IsmReleaseMemory (transCopyError.ObjectName);
  838. return FALSE;
  839. }
  840. if (GetLastError () == ERROR_FILENAME_EXCED_RANGE) {
  841. forceLogError = TRUE;
  842. }
  843. }
  844. if (appReply == APPRESPONSE_IGNORE) {
  845. if (forceLogError) {
  846. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_COPYSOURCE, transCopyError.ObjectName));
  847. } else {
  848. LOG ((
  849. LOG_WARNING,
  850. (PCSTR) MSG_IGNORE_COPYSOURCE,
  851. transCopyError.ObjectName,
  852. GetLastError (),
  853. GetLastError ()
  854. ));
  855. }
  856. IsmReleaseMemory (transCopyError.ObjectName);
  857. break;
  858. }
  859. IsmReleaseMemory (transCopyError.ObjectName);
  860. continue;
  861. }
  862. okSave = TRUE;
  863. }
  864. if (dirName != fileName) {
  865. FreePathString (dirName);
  866. }
  867. FreePathString (fileName);
  868. }
  869. } else {
  870. // this is just a directory. Let's record that we saved this
  871. nativeObjectName = IsmGetNativeObjectName (ObjectTypeId, ObjectName);
  872. MemDbSetValue (nativeObjectName, TRFLAG_FILE);
  873. IsmReleaseMemory (nativeObjectName);
  874. }
  875. }
  876. } else {
  877. GbAppendString (Buffer, TEXT("\r\n"));
  878. }
  879. IsmReleaseObject (&objectContent);
  880. }
  881. return TRUE;
  882. }
  883. BOOL
  884. WINAPI
  885. InfTransTransportSaveState (
  886. VOID
  887. )
  888. {
  889. MIG_OBJECTTYPEID objectTypeId;
  890. MIG_OBJECT_ENUM objEnum;
  891. MIG_OBJECTSTRINGHANDLE objectPattern = NULL;
  892. MIG_OBJECTSTRINGHANDLE objectName = NULL;
  893. MIG_OBJECTSTRINGHANDLE tempObjectName = NULL;
  894. MIG_CONTENT objectContent;
  895. PCTSTR infFile = NULL;
  896. HANDLE infFileHandle = NULL;
  897. MIG_OBJECTTYPEID dataTypeId;
  898. MIG_OBJECTTYPEID fileTypeId;
  899. TCHAR tempDir [MAX_PATH] = TEXT("");
  900. BOOL firstPass = TRUE;
  901. BOOL process = TRUE;
  902. GROWBUFFER writeBuffer = INIT_GROWBUFFER;
  903. MIG_OBJECTTYPEIDENUM objTypeIdEnum;
  904. PCTSTR node, leaf;
  905. PTSTR nodePtr;
  906. TCHAR savedNode;
  907. DWORD value;
  908. BOOL result = FALSE;
  909. if (!pStoreStatusOK (g_InfTransTransportPath, g_InfTransTransportStatus)) {
  910. return FALSE;
  911. }
  912. __try {
  913. IsmGetTempDirectory (tempDir, MAX_PATH);
  914. g_Platform = PLATFORM_SOURCE;
  915. objectName = IsmCreateObjectHandle (S_DATABASEFILE_LITE, NULL);
  916. if (IsmAcquireObjectEx (
  917. MIG_DATA_TYPE | PLATFORM_SOURCE,
  918. objectName,
  919. &objectContent,
  920. CONTENTTYPE_FILE,
  921. 0
  922. )) {
  923. // we have the database file, we assume it's an INF file
  924. // and we copy it to our transport location with the
  925. // migration.inf name.
  926. infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
  927. if (!CopyFile (objectContent.FileContent.ContentPath, infFile, FALSE)) {
  928. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_SAVE_ISM_INF));
  929. __leave;
  930. }
  931. IsmReleaseObject (&objectContent);
  932. } else {
  933. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
  934. __leave;
  935. }
  936. infFileHandle = BfOpenFile (infFile);
  937. if (!infFileHandle) {
  938. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_FIND_ISM_INF));
  939. __leave;
  940. }
  941. BfGoToEndOfFile (infFileHandle, 0);
  942. objectPattern = IsmCreateSimpleObjectPattern (NULL, TRUE, NULL, TRUE);
  943. dataTypeId = MIG_DATA_TYPE;
  944. fileTypeId = MIG_FILE_TYPE;
  945. if (IsmEnumFirstObjectTypeId (&objTypeIdEnum)) {
  946. do {
  947. objectTypeId = objTypeIdEnum.ObjectTypeId;
  948. if (firstPass) {
  949. WriteFileString (infFileHandle, TEXT("["));
  950. WriteFileString (infFileHandle, IsmGetObjectTypeName (objectTypeId));
  951. WriteFileString (infFileHandle, TEXT("]\r\n"));
  952. }
  953. if (IsmEnumFirstSourceObjectEx (&objEnum, objectTypeId, objectPattern, TRUE)) {
  954. do {
  955. writeBuffer.End = 0;
  956. if (IsmCheckCancel()) {
  957. IsmAbortObjectTypeIdEnum (&objTypeIdEnum);
  958. IsmAbortObjectEnum (&objEnum);
  959. __leave;
  960. }
  961. if (objectTypeId == dataTypeId && StringIMatch(objEnum.ObjectName, objectName)) {
  962. continue;
  963. }
  964. if (IsmIsPersistentObject (objEnum.ObjectTypeId, objEnum.ObjectName)) {
  965. process = TRUE;
  966. if (objectTypeId == fileTypeId) {
  967. if (firstPass) {
  968. process = pIsShortFileName (objectTypeId, objEnum.ObjectName, tempDir);
  969. } else {
  970. process = !pIsShortFileName (objectTypeId, objEnum.ObjectName, tempDir);
  971. }
  972. }
  973. if (process) {
  974. if (objectTypeId == fileTypeId) {
  975. // for files and folders we want to save all parent folders in this INF.
  976. // The reason why we do this, is to be able to reconstruct the short-long
  977. // information from this source machine once we get on the destination
  978. // machine
  979. // extract the directory information from ObjectName
  980. if (IsmCreateObjectStringsFromHandle (objEnum.ObjectName, &node, &leaf)) {
  981. // Let's walk the node and see if we saved it already.
  982. // If not, save it.
  983. nodePtr = (PTSTR)node;
  984. while (nodePtr) {
  985. nodePtr = _tcschr (nodePtr, TEXT('\\'));
  986. if (nodePtr) {
  987. savedNode = *nodePtr;
  988. *nodePtr = 0;
  989. }
  990. if (IsValidFileSpec (node)) {
  991. // let's check to see if we already added this directory
  992. value = 0;
  993. if (!MemDbGetValue (node, &value) || (value != TRFLAG_FILE)) {
  994. tempObjectName = IsmCreateObjectHandle (node, NULL);
  995. if (tempObjectName) {
  996. writeBuffer.End = 0;
  997. if (!pSaveObject (
  998. fileTypeId|PLATFORM_SOURCE,
  999. tempObjectName,
  1000. TRUE,
  1001. &writeBuffer
  1002. )) {
  1003. IsmAbortObjectTypeIdEnum (&objTypeIdEnum);
  1004. IsmAbortObjectEnum (&objEnum);
  1005. __leave;
  1006. }
  1007. if (writeBuffer.End) {
  1008. WriteFileString (infFileHandle, (PTSTR) writeBuffer.Buf);
  1009. }
  1010. IsmDestroyObjectHandle (tempObjectName);
  1011. }
  1012. }
  1013. }
  1014. if (nodePtr) {
  1015. *nodePtr = savedNode;
  1016. nodePtr = _tcsinc (nodePtr);
  1017. }
  1018. };
  1019. IsmDestroyObjectString (node);
  1020. IsmDestroyObjectString (leaf);
  1021. }
  1022. // if it's node only it was already saved above, so save only leaf ones
  1023. if (leaf) {
  1024. writeBuffer.End = 0;
  1025. if (!pSaveObject (
  1026. objEnum.ObjectTypeId,
  1027. objEnum.ObjectName,
  1028. FALSE,
  1029. &writeBuffer
  1030. )) {
  1031. IsmAbortObjectTypeIdEnum (&objTypeIdEnum);
  1032. IsmAbortObjectEnum (&objEnum);
  1033. __leave;
  1034. }
  1035. if (writeBuffer.End) {
  1036. WriteFileString (infFileHandle, (PTSTR) writeBuffer.Buf);
  1037. }
  1038. }
  1039. } else {
  1040. writeBuffer.End = 0;
  1041. if (!pSaveObject (
  1042. objEnum.ObjectTypeId,
  1043. objEnum.ObjectName,
  1044. FALSE,
  1045. &writeBuffer
  1046. )) {
  1047. IsmAbortObjectTypeIdEnum (&objTypeIdEnum);
  1048. IsmAbortObjectEnum (&objEnum);
  1049. __leave;
  1050. }
  1051. if (writeBuffer.End) {
  1052. WriteFileString (infFileHandle, (PTSTR) writeBuffer.Buf);
  1053. }
  1054. }
  1055. }
  1056. }
  1057. } while (IsmEnumNextObject (&objEnum));
  1058. }
  1059. if (!firstPass || objectTypeId != fileTypeId) {
  1060. WriteFileString (infFileHandle, TEXT("\r\n\r\n"));
  1061. }
  1062. if ((objectTypeId == fileTypeId) && firstPass) {
  1063. firstPass = FALSE;
  1064. } else {
  1065. if (!IsmEnumNextObjectTypeId (&objTypeIdEnum)) {
  1066. break;
  1067. }
  1068. firstPass = TRUE;
  1069. }
  1070. } while (TRUE);
  1071. }
  1072. result = TRUE;
  1073. }
  1074. __finally {
  1075. PushError ();
  1076. if (tempDir [0]) {
  1077. FiRemoveAllFilesInTree (tempDir);
  1078. }
  1079. IsmDestroyObjectHandle (objectName);
  1080. if (infFileHandle != NULL) {
  1081. CloseHandle (infFileHandle);
  1082. }
  1083. IsmDestroyObjectHandle (objectPattern);
  1084. FreePathString (infFile);
  1085. infFile = NULL;
  1086. PopError ();
  1087. }
  1088. PushError ();
  1089. if (result) {
  1090. pSetInfTransStatus (g_InfTransTransportStatusHandle, TRSTATUS_READY);
  1091. }
  1092. CloseHandle (g_InfTransTransportStatusHandle);
  1093. g_InfTransTransportStatusHandle = NULL;
  1094. GbFree (&writeBuffer);
  1095. if (result && g_EstimateSizeOnly) {
  1096. result = pWriteEstimateFile ();
  1097. }
  1098. if (!result) {
  1099. FiRemoveAllFilesInTree (g_InfTransTransportPath);
  1100. }
  1101. PopError ();
  1102. return result;
  1103. }
  1104. BOOL
  1105. pSaveObjectContent (
  1106. IN MIG_OBJECTTYPEID ObjectTypeId,
  1107. IN PCTSTR ObjectName,
  1108. IN PCTSTR DecoratedObject,
  1109. IN PMIG_CONTENT ObjectContent
  1110. )
  1111. {
  1112. PCTSTR fileName;
  1113. BOOL result = FALSE;
  1114. if (ObjectContent->ContentInFile) {
  1115. MemDbSetValue (DecoratedObject, TRFLAG_FILE);
  1116. if (pObjectNameToFileName (ObjectName, &fileName, NULL)) {
  1117. if (DoesFileExist (fileName)) {
  1118. MemDbAddSingleLinkage (DecoratedObject, fileName, 0);
  1119. }
  1120. FreePathString (fileName);
  1121. }
  1122. } else {
  1123. MemDbSetValue (DecoratedObject, TRFLAG_MEMORY);
  1124. if (ObjectContent->MemoryContent.ContentSize &&
  1125. ObjectContent->MemoryContent.ContentBytes
  1126. ) {
  1127. MemDbSetUnorderedBlob (
  1128. DecoratedObject,
  1129. 0,
  1130. ObjectContent->MemoryContent.ContentBytes,
  1131. ObjectContent->MemoryContent.ContentSize
  1132. );
  1133. }
  1134. }
  1135. result = pInfTransSaveDetails (DecoratedObject, &(ObjectContent->Details));
  1136. return result;
  1137. }
  1138. BOOL
  1139. WINAPI
  1140. InfTransTransportBeginApply (
  1141. VOID
  1142. )
  1143. {
  1144. PCTSTR infFile;
  1145. HINF infHandle;
  1146. INFSTRUCT is = INITINFSTRUCT_PMHANDLE;
  1147. MIG_OBJECTTYPEID objectTypeId;
  1148. GROWBUFFER buff = INIT_GROWBUFFER;
  1149. PCTSTR field;
  1150. MIG_CONTENT objectContent;
  1151. MIG_OBJECTSTRINGHANDLE objectName;
  1152. UINT index;
  1153. PCTSTR decoratedObject = NULL;
  1154. DWORD status = 0;
  1155. PTSTR decodedString = NULL;
  1156. MIG_OBJECTTYPEIDENUM objTypeIdEnum;
  1157. DWORD error;
  1158. g_Platform = PLATFORM_DESTINATION;
  1159. while (status != TRSTATUS_READY) {
  1160. status = pGetInfTransStatus (g_InfTransTransportStatus);
  1161. switch (status) {
  1162. case TRSTATUS_LOCKED:
  1163. if (!IsmSendMessageToApp (TRANSPORTMESSAGE_IMAGE_LOCKED, 0)) {
  1164. LOG ((LOG_ERROR, (PCSTR) MSG_TRANSPORT_DIR_BUSY , g_InfTransTransportPath));
  1165. error = GetLastError ();
  1166. if ((error != ERROR_ACCESS_DENIED) &&
  1167. (error != ERROR_SHARING_VIOLATION)
  1168. ) {
  1169. SetLastError (ERROR_ACCESS_DENIED);
  1170. }
  1171. return FALSE;
  1172. }
  1173. break;
  1174. case TRSTATUS_DIRTY:
  1175. SetLastError (ERROR_ACCESS_DENIED);
  1176. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_InfTransTransportPath));
  1177. return FALSE;
  1178. case TRSTATUS_READY:
  1179. break;
  1180. default:
  1181. SetLastError (ERROR_INVALID_DATA);
  1182. LOG ((LOG_ERROR, (PCSTR) MSG_INVALID_IMAGE, g_InfTransTransportPath));
  1183. return FALSE;
  1184. }
  1185. }
  1186. g_InfTransTransportStatusHandle = BfOpenReadFile (g_InfTransTransportStatus);
  1187. if (!g_InfTransTransportStatusHandle) {
  1188. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_STATUS_FILE, g_InfTransTransportStatus));
  1189. return FALSE;
  1190. }
  1191. infFile = JoinPaths (g_InfTransTransportPath, S_TRANSPORT_INF_FILE);
  1192. // add the database file in memdb so we can serve AcquireObject from the ISM
  1193. objectName = IsmCreateObjectHandle (S_DATABASEFILE_LITE, NULL);
  1194. decoratedObject = pInfTransBuildDecoratedObject (MIG_DATA_TYPE | PLATFORM_SOURCE, objectName);
  1195. MemDbSetValue (decoratedObject, TRFLAG_FILE);
  1196. MemDbAddSingleLinkage (decoratedObject, infFile, 0);
  1197. pInfTransDestroyDecoratedObject (decoratedObject);
  1198. IsmDestroyObjectHandle (objectName);
  1199. infHandle = InfOpenInfFile (infFile);
  1200. if (infHandle == INVALID_HANDLE_VALUE) {
  1201. LOG ((LOG_ERROR, (PCSTR) MSG_CANT_OPEN_ISM_INF, infFile));
  1202. FreePathString (infFile);
  1203. return FALSE;
  1204. }
  1205. if (IsmEnumFirstObjectTypeId (&objTypeIdEnum)) {
  1206. do {
  1207. objectTypeId = objTypeIdEnum.ObjectTypeId;
  1208. if (InfFindFirstLine (infHandle, IsmGetObjectTypeName (objectTypeId), NULL, &is)) {
  1209. do {
  1210. index = 1;
  1211. buff.End = 0;
  1212. for (;;) {
  1213. field = InfGetStringField (&is, index);
  1214. if (!field) {
  1215. break;
  1216. }
  1217. if (*field) {
  1218. decodedString = DuplicatePathString (field, 0);
  1219. if (DecodeRuleChars (decodedString, field) != NULL) {
  1220. GbCopyString (&buff, decodedString);
  1221. } else {
  1222. GbCopyString (&buff, field);
  1223. }
  1224. FreePathString (decodedString);
  1225. } else {
  1226. GbCopyString (&buff, TEXT("<empty>"));
  1227. }
  1228. index ++;
  1229. }
  1230. if (buff.End) {
  1231. GbCopyString (&buff, TEXT(""));
  1232. if (IsmConvertMultiSzToObject (
  1233. objectTypeId,
  1234. (PCTSTR)buff.Buf,
  1235. &objectName,
  1236. &objectContent
  1237. )) {
  1238. // now save the object data into our database
  1239. // for future reference
  1240. decoratedObject = pInfTransBuildDecoratedObject (objectTypeId | PLATFORM_SOURCE, objectName);
  1241. pSaveObjectContent (objectTypeId | g_Platform, objectName, decoratedObject, &objectContent);
  1242. pInfTransDestroyDecoratedObject (decoratedObject);
  1243. IsmDestroyObjectHandle (objectName);
  1244. if ((objectContent.Details.DetailsSize) &&
  1245. (objectContent.Details.DetailsData)
  1246. ) {
  1247. IsmReleaseMemory (objectContent.Details.DetailsData);
  1248. }
  1249. if (objectContent.ContentInFile) {
  1250. if (objectContent.FileContent.ContentPath) {
  1251. IsmReleaseMemory (objectContent.FileContent.ContentPath);
  1252. }
  1253. } else {
  1254. if ((objectContent.MemoryContent.ContentSize) &&
  1255. (objectContent.MemoryContent.ContentBytes)
  1256. ) {
  1257. IsmReleaseMemory (objectContent.MemoryContent.ContentBytes);
  1258. }
  1259. }
  1260. }
  1261. }
  1262. } while (InfFindNextLine (&is));
  1263. }
  1264. } while (IsmEnumNextObjectTypeId (&objTypeIdEnum));
  1265. }
  1266. GbFree (&buff);
  1267. InfCleanUpInfStruct (&is);
  1268. InfCloseInfFile (infHandle);
  1269. FreePathString (infFile);
  1270. return TRUE;
  1271. }
  1272. VOID
  1273. WINAPI
  1274. InfTransTransportEndApply (
  1275. VOID
  1276. )
  1277. {
  1278. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  1279. CloseHandle (g_InfTransTransportStatusHandle);
  1280. g_InfTransTransportStatusHandle = NULL;
  1281. }
  1282. VOID
  1283. WINAPI
  1284. InfTransTransportTerminate (
  1285. VOID
  1286. )
  1287. {
  1288. if (g_InfTransStoragePath) {
  1289. FreePathString (g_InfTransStoragePath);
  1290. g_InfTransStoragePath = NULL;
  1291. }
  1292. if (g_InfTransTransportPath) {
  1293. FreePathString (g_InfTransTransportPath);
  1294. g_InfTransTransportPath = NULL;
  1295. }
  1296. if (g_InfTransTransportStatus) {
  1297. FreePathString (g_InfTransTransportStatus);
  1298. g_InfTransTransportStatus = NULL;
  1299. }
  1300. }
  1301. BOOL
  1302. WINAPI
  1303. InfTransTransportAcquireObject (
  1304. IN MIG_OBJECTTYPEID ObjectTypeId,
  1305. IN MIG_OBJECTSTRINGHANDLE ObjectName,
  1306. OUT PMIG_CONTENT ObjectContent, CALLER_INITIALIZED
  1307. IN MIG_CONTENTTYPE ContentType,
  1308. IN UINT MemoryContentLimit
  1309. )
  1310. {
  1311. UINT value;
  1312. PCBYTE memValue;
  1313. UINT memValueSize;
  1314. PCTSTR fileValue = NULL;
  1315. BOOL valueInFile;
  1316. KEYHANDLE keyHandle;
  1317. PALLOCSTATE allocState;
  1318. PCTSTR detailsKey = NULL;
  1319. PBYTE details;
  1320. UINT detailsSize;
  1321. PCTSTR decoratedObject = NULL;
  1322. HANDLE fileHandle;
  1323. BOOL result = FALSE;
  1324. if (!ObjectContent) {
  1325. return FALSE;
  1326. }
  1327. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  1328. MYASSERT ((ObjectTypeId & PLATFORM_MASK) == PLATFORM_SOURCE);
  1329. decoratedObject = pInfTransBuildDecoratedObject (ObjectTypeId, ObjectName);
  1330. allocState = (PALLOCSTATE) MemAllocZeroed (sizeof (ALLOCSTATE));
  1331. if (MemDbGetValue (decoratedObject, &value)) {
  1332. if (value == TRFLAG_FILE) {
  1333. valueInFile = TRUE;
  1334. keyHandle = MemDbGetSingleLinkage (decoratedObject, 0, 0);
  1335. if (keyHandle) {
  1336. fileValue = MemDbGetKeyFromHandle (keyHandle, 0);
  1337. result = fileValue != NULL;
  1338. } else {
  1339. fileValue = NULL;
  1340. result = TRUE;
  1341. }
  1342. } else if (value == TRFLAG_MEMORY) {
  1343. valueInFile = FALSE;
  1344. memValueSize = 0;
  1345. memValue = MemDbGetUnorderedBlob (decoratedObject, 0, &memValueSize);
  1346. result = TRUE;
  1347. } else {
  1348. LOG ((LOG_ERROR, (PCSTR) MSG_UNSUPPORTED_DATA, value));
  1349. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  1350. }
  1351. if (result) {
  1352. result = FALSE;
  1353. if (valueInFile) {
  1354. if ((ContentType == CONTENTTYPE_ANY) ||
  1355. (ContentType == CONTENTTYPE_FILE) ||
  1356. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  1357. ) {
  1358. // this is stored as a file and it's wanted as a file
  1359. ObjectContent->ObjectTypeId = ObjectTypeId;
  1360. ObjectContent->ContentInFile = TRUE;
  1361. if (fileValue) {
  1362. ObjectContent->FileContent.ContentPath = DuplicatePathString (fileValue, 0);
  1363. ObjectContent->FileContent.ContentSize = BfGetFileSize (ObjectContent->FileContent.ContentPath);
  1364. } else {
  1365. ObjectContent->FileContent.ContentSize = 0;
  1366. ObjectContent->FileContent.ContentPath = NULL;
  1367. }
  1368. result = TRUE;
  1369. } else {
  1370. // this is stored as a file and it's wanted as memory
  1371. ObjectContent->ObjectTypeId = ObjectTypeId;
  1372. ObjectContent->ContentInFile = FALSE;
  1373. if (fileValue) {
  1374. ObjectContent->MemoryContent.ContentSize = (UINT) BfGetFileSize (fileValue);
  1375. ObjectContent->MemoryContent.ContentBytes = MapFileIntoMemory (
  1376. fileValue,
  1377. &allocState->FileHandle,
  1378. &allocState->MapHandle
  1379. );
  1380. result = (ObjectContent->MemoryContent.ContentBytes != NULL);
  1381. } else {
  1382. ObjectContent->MemoryContent.ContentSize = 0;
  1383. ObjectContent->MemoryContent.ContentBytes = NULL;
  1384. result = TRUE;
  1385. }
  1386. }
  1387. MemDbReleaseMemory (fileValue);
  1388. } else {
  1389. if ((ContentType == CONTENTTYPE_ANY) ||
  1390. (ContentType == CONTENTTYPE_MEMORY) ||
  1391. (ContentType == CONTENTTYPE_DETAILS_ONLY)
  1392. ) {
  1393. // this is stored as memory and it's wanted as memory
  1394. ObjectContent->ObjectTypeId = ObjectTypeId;
  1395. ObjectContent->ContentInFile = FALSE;
  1396. ObjectContent->MemoryContent.ContentSize = memValueSize;
  1397. ObjectContent->MemoryContent.ContentBytes = memValue;
  1398. result = TRUE;
  1399. } else {
  1400. // this is stored as memory and it's wanted as a file
  1401. if (memValue) {
  1402. if (IsmGetTempFile (allocState->TempFile, ARRAYSIZE(allocState->TempFile))) {
  1403. fileHandle = BfCreateFile (allocState->TempFile);
  1404. if (fileHandle) {
  1405. if (BfWriteFile (fileHandle, memValue, memValueSize)) {
  1406. ObjectContent->ObjectTypeId = ObjectTypeId;
  1407. ObjectContent->ContentInFile = TRUE;
  1408. ObjectContent->FileContent.ContentSize = memValueSize;
  1409. ObjectContent->FileContent.ContentPath = DuplicatePathString (allocState->TempFile, 0);
  1410. result = TRUE;
  1411. }
  1412. CloseHandle (fileHandle);
  1413. }
  1414. }
  1415. MemDbReleaseMemory (memValue);
  1416. } else {
  1417. ObjectContent->ObjectTypeId = ObjectTypeId;
  1418. ObjectContent->ContentInFile = TRUE;
  1419. ObjectContent->FileContent.ContentSize = 0;
  1420. ObjectContent->FileContent.ContentPath = NULL;
  1421. }
  1422. }
  1423. }
  1424. }
  1425. } else {
  1426. SetLastError (ERROR_RESOURCE_NAME_NOT_FOUND);
  1427. }
  1428. if (result) {
  1429. //
  1430. // Fill the details
  1431. //
  1432. detailsKey = JoinText (S_DETAILS_PREFIX, decoratedObject);
  1433. details = MemDbGetUnorderedBlob (detailsKey, 0, &detailsSize);
  1434. if (!details) {
  1435. detailsSize = 0;
  1436. }
  1437. allocState->DetailsPtr = details;
  1438. ObjectContent->Details.DetailsSize = detailsSize;
  1439. ObjectContent->Details.DetailsData = details;
  1440. FreeText (detailsKey);
  1441. ObjectContent->TransHandle = allocState;
  1442. }
  1443. if (!result) {
  1444. FreeAlloc (allocState);
  1445. }
  1446. FreePathString (decoratedObject);
  1447. return result;
  1448. }
  1449. BOOL
  1450. WINAPI
  1451. InfTransTransportReleaseObject (
  1452. IN OUT PMIG_CONTENT ObjectContent
  1453. )
  1454. {
  1455. PALLOCSTATE allocState;
  1456. MYASSERT (g_Platform == PLATFORM_DESTINATION);
  1457. allocState = (PALLOCSTATE) ObjectContent->TransHandle;
  1458. if (ObjectContent->ContentInFile) {
  1459. FreePathString (ObjectContent->FileContent.ContentPath);
  1460. if (allocState && allocState->TempFile[0]) {
  1461. DeleteFile (allocState->TempFile);
  1462. }
  1463. } else {
  1464. if (allocState && allocState->FileHandle && allocState->MapHandle) {
  1465. UnmapFile (
  1466. ObjectContent->MemoryContent.ContentBytes,
  1467. allocState->MapHandle,
  1468. allocState->FileHandle
  1469. );
  1470. } else {
  1471. MemDbReleaseMemory (ObjectContent->MemoryContent.ContentBytes);
  1472. }
  1473. }
  1474. if (allocState && allocState->DetailsPtr) {
  1475. MemDbReleaseMemory (allocState->DetailsPtr);
  1476. }
  1477. FreeAlloc (allocState);
  1478. return TRUE;
  1479. }