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.

2386 lines
78 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. handler.c
  5. Abstract:
  6. This module contains the individual API handler routines for the INSTALER program
  7. Author:
  8. Steve Wood (stevewo) 10-Aug-1994
  9. Revision History:
  10. --*/
  11. #include "instaler.h"
  12. #include <ntstatus.dbg>
  13. BOOLEAN
  14. HandleBreakpoint(
  15. PPROCESS_INFO Process,
  16. PTHREAD_INFO Thread,
  17. PBREAKPOINT_INFO Breakpoint
  18. )
  19. {
  20. BOOLEAN Result;
  21. API_SAVED_PARAMETERS SavedParameters;
  22. UCHAR ApiIndex;
  23. PBREAKPOINT_INFO ReturnBreakpoint;
  24. Result = FALSE;
  25. ApiIndex = Breakpoint->ApiIndex;
  26. if (ApiInfo[ ApiIndex ].ModuleIndex < Thread->ModuleIndexCurrentlyIn) {
  27. return TRUE;
  28. }
  29. DbgEvent( DBGEVENT, ( "Processing Breakpoint at %ws!%s\n",
  30. Breakpoint->ModuleName,
  31. Breakpoint->ProcedureName
  32. )
  33. );
  34. if (!Breakpoint->SavedParametersValid) {
  35. memset( &SavedParameters, 0, sizeof( SavedParameters ) );
  36. Result = TRUE;
  37. if (ExtractProcedureParameters( Process,
  38. Thread,
  39. (PVOID)&SavedParameters.ReturnAddress,
  40. ApiInfo[ ApiIndex ].SizeOfParameters,
  41. (PULONG)&SavedParameters.InputParameters
  42. )
  43. ) {
  44. if (ApiInfo[ ApiIndex ].EntryPointHandler == NULL ||
  45. (ApiInfo[ ApiIndex ].EntryPointHandler)( Process,
  46. Thread,
  47. &SavedParameters
  48. )
  49. ) {
  50. if (SavedParameters.ReturnAddress == NULL) {
  51. Result = FALSE;
  52. }
  53. else
  54. if (CreateBreakpoint( SavedParameters.ReturnAddress,
  55. Process,
  56. Thread, // thread specific
  57. ApiIndex,
  58. &SavedParameters,
  59. &ReturnBreakpoint
  60. )
  61. ) {
  62. ReturnBreakpoint->ModuleName = L"Return from";
  63. ReturnBreakpoint->ProcedureName = Breakpoint->ProcedureName;
  64. Thread->ModuleIndexCurrentlyIn = ApiInfo[ ApiIndex ].ModuleIndex;
  65. SuspendAllButThisThread( Process, Thread );
  66. }
  67. }
  68. }
  69. #if DBG
  70. TrimTemporaryBuffer();
  71. #endif
  72. }
  73. else {
  74. if (UndoReturnAddressBreakpoint( Process, Thread ) &&
  75. ExtractProcedureReturnValue( Process,
  76. Thread,
  77. &Breakpoint->SavedParameters.ReturnValue,
  78. ApiInfo[ ApiIndex ].SizeOfReturnValue
  79. )
  80. ) {
  81. Breakpoint->SavedParameters.ReturnValueValid = TRUE;
  82. if (ApiInfo[ ApiIndex ].EntryPointHandler != NULL) {
  83. (ApiInfo[ ApiIndex ].EntryPointHandler)( Process,
  84. Thread,
  85. &Breakpoint->SavedParameters
  86. );
  87. }
  88. }
  89. Thread->ModuleIndexCurrentlyIn = 0;
  90. FreeSavedCallState( &Breakpoint->SavedParameters.SavedCallState );
  91. DestroyBreakpoint( Breakpoint->Address, Process, Thread );
  92. ResumeAllButThisThread( Process, Thread );
  93. #if DBG
  94. TrimTemporaryBuffer();
  95. #endif
  96. Result = FALSE;
  97. }
  98. return Result;
  99. }
  100. BOOLEAN
  101. CreateSavedCallState(
  102. PPROCESS_INFO Process,
  103. PAPI_SAVED_CALL_STATE SavedCallState,
  104. API_ACTION Action,
  105. ULONG Type,
  106. PWSTR FullName,
  107. ...
  108. )
  109. {
  110. va_list arglist;
  111. va_start( arglist, FullName );
  112. SavedCallState->Action = Action;
  113. SavedCallState->Type = Type;
  114. SavedCallState->FullName = FullName;
  115. switch (Action) {
  116. case OpenPath:
  117. SavedCallState->PathOpen.InheritHandle = va_arg( arglist, BOOLEAN );
  118. SavedCallState->PathOpen.WriteAccessRequested = va_arg( arglist, BOOLEAN );
  119. SavedCallState->PathOpen.ResultHandleAddress = va_arg( arglist, PHANDLE );
  120. break;
  121. case RenamePath:
  122. SavedCallState->PathRename.NewName = va_arg( arglist, PWSTR );
  123. SavedCallState->PathRename.ReplaceIfExists = va_arg( arglist, BOOLEAN );
  124. break;
  125. case DeletePath:
  126. case QueryPath:
  127. case SetValue:
  128. case DeleteValue:
  129. break;
  130. case WriteIniValue:
  131. SavedCallState->SetIniValue.SectionName = va_arg( arglist, PWSTR );
  132. SavedCallState->SetIniValue.VariableName = va_arg( arglist, PWSTR );
  133. SavedCallState->SetIniValue.VariableValue = va_arg( arglist, PWSTR );
  134. break;
  135. case WriteIniSection:
  136. SavedCallState->SetIniSection.SectionName = va_arg( arglist, PWSTR );
  137. SavedCallState->SetIniSection.SectionValue = va_arg( arglist, PWSTR );
  138. break;
  139. default:
  140. return FALSE;
  141. }
  142. va_end( arglist );
  143. return TRUE;
  144. }
  145. VOID
  146. FreeSavedCallState(
  147. PAPI_SAVED_CALL_STATE CallState
  148. )
  149. {
  150. switch (CallState->Action) {
  151. case WriteIniValue:
  152. FreeMem( &CallState->SetIniValue.VariableValue );
  153. break;
  154. case WriteIniSection:
  155. FreeMem( &CallState->SetIniSection.SectionValue );
  156. break;
  157. }
  158. return;
  159. }
  160. BOOLEAN
  161. CaptureObjectAttributes(
  162. PPROCESS_INFO Process,
  163. POBJECT_ATTRIBUTES ObjectAttributesAddress,
  164. POBJECT_ATTRIBUTES ObjectAttributes,
  165. PUNICODE_STRING ObjectName
  166. )
  167. {
  168. if (ObjectAttributesAddress != NULL &&
  169. ReadMemory( Process,
  170. ObjectAttributesAddress,
  171. ObjectAttributes,
  172. sizeof( *ObjectAttributes ),
  173. "object attributes"
  174. ) &&
  175. ObjectAttributes->ObjectName != NULL &&
  176. ReadMemory( Process,
  177. ObjectAttributes->ObjectName,
  178. ObjectName,
  179. sizeof( *ObjectName ),
  180. "object name string"
  181. )
  182. ) {
  183. return TRUE;
  184. }
  185. else {
  186. return FALSE;
  187. }
  188. }
  189. BOOLEAN
  190. CaptureFullName(
  191. PPROCESS_INFO Process,
  192. ULONG Type,
  193. HANDLE RootDirectory,
  194. PWSTR Name,
  195. ULONG Length,
  196. PWSTR *ReturnedFullName
  197. )
  198. {
  199. POPENHANDLE_INFO HandleInfo;
  200. UNICODE_STRING FullName;
  201. ULONG LengthOfName;
  202. PWSTR s;
  203. BOOLEAN Result;
  204. *ReturnedFullName = NULL;
  205. if (RootDirectory != NULL) {
  206. HandleInfo = FindOpenHandle( Process,
  207. RootDirectory,
  208. Type
  209. );
  210. if (HandleInfo == NULL) {
  211. //
  212. // If handle not found then we dont care about this open
  213. // as it is relative to a device that is not local.
  214. //
  215. return FALSE;
  216. }
  217. }
  218. else {
  219. HandleInfo = NULL;
  220. }
  221. LengthOfName = Length + sizeof( UNICODE_NULL );
  222. if (HandleInfo != NULL) {
  223. LengthOfName += HandleInfo->LengthOfName +
  224. sizeof( OBJ_NAME_PATH_SEPARATOR );
  225. }
  226. FullName.Buffer = AllocMem( LengthOfName );
  227. if (FullName.Buffer == NULL) {
  228. return FALSE;
  229. }
  230. s = FullName.Buffer;
  231. if (HandleInfo != NULL) {
  232. RtlMoveMemory( s,
  233. HandleInfo->Name,
  234. HandleInfo->LengthOfName
  235. );
  236. s = &FullName.Buffer[ HandleInfo->LengthOfName / sizeof( WCHAR ) ];
  237. if (s[-1] != OBJ_NAME_PATH_SEPARATOR) {
  238. *s++ = OBJ_NAME_PATH_SEPARATOR;
  239. }
  240. }
  241. if (!ReadMemory( Process,
  242. Name,
  243. s,
  244. Length,
  245. "object name buffer"
  246. )
  247. ) {
  248. FreeMem( &FullName.Buffer );
  249. return FALSE;
  250. }
  251. s = &s[ Length / sizeof( WCHAR ) ];
  252. *s = UNICODE_NULL;
  253. FullName.Length = (PCHAR)s - (PCHAR)FullName.Buffer;
  254. FullName.MaximumLength = (USHORT)(FullName.Length + sizeof( UNICODE_NULL ));
  255. if (HandleInfo == NULL && Type == HANDLE_TYPE_FILE) {
  256. Result = IsDriveLetterPath( &FullName );
  257. }
  258. else {
  259. Result = TRUE;
  260. }
  261. *ReturnedFullName = AddName( &FullName );
  262. FreeMem( &FullName.Buffer );
  263. return Result;
  264. }
  265. BOOLEAN
  266. CaptureOpenState(
  267. PPROCESS_INFO Process,
  268. PAPI_SAVED_PARAMETERS Parameters,
  269. POBJECT_ATTRIBUTES ObjectAttributesAddress,
  270. BOOLEAN WriteAccess,
  271. PHANDLE ResultHandleAddress,
  272. ULONG Type
  273. )
  274. {
  275. OBJECT_ATTRIBUTES ObjectAttributes;
  276. UNICODE_STRING ObjectName;
  277. PWSTR FullName;
  278. BOOLEAN Result;
  279. Result = FALSE;
  280. if (CaptureObjectAttributes( Process,
  281. ObjectAttributesAddress,
  282. &ObjectAttributes,
  283. &ObjectName
  284. ) &&
  285. CaptureFullName( Process,
  286. Type,
  287. ObjectAttributes.RootDirectory,
  288. ObjectName.Buffer,
  289. ObjectName.Length,
  290. &FullName
  291. ) &&
  292. CreateSavedCallState( Process,
  293. &Parameters->SavedCallState,
  294. OpenPath,
  295. Type,
  296. FullName,
  297. (BOOLEAN)((ObjectAttributes.Attributes & OBJ_INHERIT) != 0),
  298. WriteAccess,
  299. ResultHandleAddress
  300. )
  301. ) {
  302. if (Type == HANDLE_TYPE_FILE) {
  303. Result = CreateFileReference( FullName,
  304. Parameters->SavedCallState.PathOpen.WriteAccessRequested,
  305. (PFILE_REFERENCE *)&Parameters->SavedCallState.Reference
  306. );
  307. }
  308. else {
  309. Result = CreateKeyReference( FullName,
  310. Parameters->SavedCallState.PathOpen.WriteAccessRequested,
  311. (PKEY_REFERENCE *)&Parameters->SavedCallState.Reference
  312. );
  313. }
  314. }
  315. return Result;
  316. }
  317. BOOLEAN
  318. CompleteOpenState(
  319. PPROCESS_INFO Process,
  320. PAPI_SAVED_PARAMETERS Parameters
  321. )
  322. {
  323. PAPI_SAVED_CALL_STATE p = &Parameters->SavedCallState;
  324. HANDLE Handle;
  325. BOOLEAN CallSuccessful;
  326. PFILE_REFERENCE FileReference;
  327. PKEY_REFERENCE KeyReference;
  328. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong ) &&
  329. ReadMemory( Process,
  330. p->PathOpen.ResultHandleAddress,
  331. &Handle,
  332. sizeof( Handle ),
  333. "result handle"
  334. ) &&
  335. AddOpenHandle( Process,
  336. Handle,
  337. p->Type,
  338. p->FullName,
  339. p->PathOpen.InheritHandle
  340. )
  341. ) {
  342. CallSuccessful = TRUE;
  343. }
  344. else {
  345. CallSuccessful = FALSE;
  346. }
  347. IncrementOpenCount( p->FullName, CallSuccessful );
  348. if (p->Type == HANDLE_TYPE_FILE) {
  349. FileReference = (PFILE_REFERENCE)p->Reference;
  350. CompleteFileReference( FileReference,
  351. CallSuccessful,
  352. FALSE,
  353. NULL
  354. );
  355. }
  356. else
  357. if (p->Type == HANDLE_TYPE_KEY) {
  358. KeyReference = (PKEY_REFERENCE)p->Reference;
  359. CompleteKeyReference( (PKEY_REFERENCE)p->Reference,
  360. CallSuccessful,
  361. FALSE
  362. );
  363. }
  364. return TRUE;
  365. }
  366. #if TRACE_ENABLED
  367. ENUM_TYPE_NAMES FileAccessNames[] = {
  368. FILE_READ_DATA, "FILE_READ_DATA",
  369. FILE_READ_DATA, "FILE_READ_DATA",
  370. FILE_WRITE_DATA, "FILE_WRITE_DATA",
  371. FILE_APPEND_DATA, "FILE_APPEND_DATA",
  372. FILE_READ_EA, "FILE_READ_EA",
  373. FILE_WRITE_EA, "FILE_WRITE_EA",
  374. FILE_EXECUTE, "FILE_EXECUTE",
  375. FILE_DELETE_CHILD, "FILE_DELETE_CHILD",
  376. FILE_READ_ATTRIBUTES, "FILE_READ_ATTRIBUTES",
  377. FILE_WRITE_ATTRIBUTES, "FILE_WRITE_ATTRIBUTES",
  378. DELETE, "DELETE",
  379. READ_CONTROL, "READ_CONTROL",
  380. WRITE_DAC, "WRITE_DAC",
  381. WRITE_OWNER, "WRITE_OWNER",
  382. SYNCHRONIZE, "SYNCHRONIZE",
  383. GENERIC_READ, "GENERIC_READ",
  384. GENERIC_WRITE, "GENERIC_WRITE",
  385. GENERIC_EXECUTE, "GENERIC_EXECUTE",
  386. GENERIC_ALL, "GENERIC_ALL",
  387. 0xFFFFFFFF, "%x"
  388. };
  389. ENUM_TYPE_NAMES FileShareNames[] = {
  390. FILE_SHARE_READ, "FILE_SHARE_READ",
  391. FILE_SHARE_WRITE, "FILE_SHARE_WRITE",
  392. FILE_SHARE_DELETE, "FILE_SHARE_DELETE",
  393. 0xFFFFFFFF, "FILE_SHARE_NONE"
  394. };
  395. ENUM_TYPE_NAMES FileCreateDispositionNames[] = {
  396. FILE_SUPERSEDE, "FILE_SUPERSEDE",
  397. FILE_OPEN, "FILE_OPEN",
  398. FILE_CREATE, "FILE_CREATE",
  399. FILE_OPEN_IF, "FILE_OPEN_IF",
  400. FILE_OVERWRITE, "FILE_OVERWRITE",
  401. FILE_OVERWRITE_IF, "FILE_OVERWRITE_IF",
  402. 0xFFFFFFFF, "%x"
  403. };
  404. ENUM_TYPE_NAMES FileCreateOptionNames[] = {
  405. FILE_DIRECTORY_FILE, "FILE_DIRECTORY_FILE",
  406. FILE_WRITE_THROUGH, "FILE_WRITE_THROUGH",
  407. FILE_SEQUENTIAL_ONLY, "FILE_SEQUENTIAL_ONLY",
  408. FILE_NO_INTERMEDIATE_BUFFERING, "FILE_NO_INTERMEDIATE_BUFFERING",
  409. FILE_SYNCHRONOUS_IO_ALERT, "FILE_SYNCHRONOUS_IO_ALERT",
  410. FILE_SYNCHRONOUS_IO_NONALERT, "FILE_SYNCHRONOUS_IO_NONALERT",
  411. FILE_NON_DIRECTORY_FILE, "FILE_NON_DIRECTORY_FILE",
  412. FILE_CREATE_TREE_CONNECTION, "FILE_CREATE_TREE_CONNECTION",
  413. FILE_COMPLETE_IF_OPLOCKED, "FILE_COMPLETE_IF_OPLOCKED",
  414. FILE_NO_EA_KNOWLEDGE, "FILE_NO_EA_KNOWLEDGE",
  415. FILE_RANDOM_ACCESS, "FILE_RANDOM_ACCESS",
  416. FILE_DELETE_ON_CLOSE, "FILE_DELETE_ON_CLOSE",
  417. FILE_OPEN_BY_FILE_ID, "FILE_OPEN_BY_FILE_ID",
  418. FILE_OPEN_FOR_BACKUP_INTENT, "FILE_OPEN_FOR_BACKUP_INTENT",
  419. FILE_NO_COMPRESSION, "FILE_NO_COMPRESSION",
  420. 0xFFFFFFFF, "%x"
  421. };
  422. ENUM_TYPE_NAMES FileIoStatusInfoNames[] = {
  423. FILE_SUPERSEDED, "FILE_SUPERSEDED",
  424. FILE_OPENED, "FILE_OPENED",
  425. FILE_CREATED, "FILE_CREATED",
  426. FILE_OVERWRITTEN, "FILE_OVERWRITTEN",
  427. FILE_EXISTS, "FILE_EXISTS",
  428. FILE_DOES_NOT_EXIST, "FILE_DOES_NOT_EXIST",
  429. 0xFFFFFFFF, "%x"
  430. };
  431. ENUM_TYPE_NAMES SetFileInfoClassNames[] = {
  432. FileDirectoryInformation, "FileDirectoryInformation",
  433. FileFullDirectoryInformation, "FileFullDirectoryInformation",
  434. FileBothDirectoryInformation, "FileBothDirectoryInformation",
  435. FileBasicInformation, "FileBasicInformation",
  436. FileStandardInformation, "FileStandardInformation",
  437. FileInternalInformation, "FileInternalInformation",
  438. FileEaInformation, "FileEaInformation",
  439. FileAccessInformation, "FileAccessInformation",
  440. FileNameInformation, "FileNameInformation",
  441. FileRenameInformation, "FileRenameInformation",
  442. FileLinkInformation, "FileLinkInformation",
  443. FileNamesInformation, "FileNamesInformation",
  444. FileDispositionInformation, "FileDispositionInformation",
  445. FilePositionInformation, "FilePositionInformation",
  446. FileFullEaInformation, "FileFullEaInformation",
  447. FileModeInformation, "FileModeInformation",
  448. FileAlignmentInformation, "FileAlignmentInformation",
  449. FileAllInformation, "FileAllInformation",
  450. FileAllocationInformation, "FileAllocationInformation",
  451. FileEndOfFileInformation, "FileEndOfFileInformation",
  452. FileAlternateNameInformation, "FileAlternateNameInformation",
  453. FileStreamInformation, "FileStreamInformation",
  454. FilePipeInformation, "FilePipeInformation",
  455. FilePipeLocalInformation, "FilePipeLocalInformation",
  456. FilePipeRemoteInformation, "FilePipeRemoteInformation",
  457. FileMailslotQueryInformation, "FileMailslotQueryInformation",
  458. FileMailslotSetInformation, "FileMailslotSetInformation",
  459. FileCompressionInformation, "FileCompressionInformation",
  460. FileCompletionInformation, "FileCompletionInformation",
  461. FileMoveClusterInformation, "FileMoveClusterInformation",
  462. 0xFFFFFFFF, "%x"
  463. };
  464. ENUM_TYPE_NAMES KeyCreateOptionNames[] = {
  465. REG_OPTION_VOLATILE, "REG_OPTION_VOLATILE",
  466. REG_OPTION_CREATE_LINK, "REG_OPTION_CREATE_LINK",
  467. REG_OPTION_BACKUP_RESTORE, "REG_OPTION_BACKUP_RESTORE",
  468. 0xFFFFFFFF, "%x"
  469. };
  470. ENUM_TYPE_NAMES KeyDispositionNames[] = {
  471. REG_CREATED_NEW_KEY, "REG_CREATED_NEW_KEY",
  472. REG_OPENED_EXISTING_KEY, "REG_OPENED_EXISTING_KEY",
  473. 0xFFFFFFFF, "%x"
  474. };
  475. #endif // TRACE_ENABLED
  476. BOOLEAN
  477. IsFileWriteAccessRequested(
  478. ACCESS_MASK DesiredAccess,
  479. ULONG CreateDisposition
  480. )
  481. {
  482. if (DesiredAccess & (GENERIC_WRITE |
  483. GENERIC_ALL |
  484. DELETE |
  485. FILE_WRITE_DATA |
  486. FILE_APPEND_DATA
  487. )
  488. ) {
  489. return TRUE;
  490. }
  491. if (CreateDisposition != FILE_OPEN && CreateDisposition != FILE_OPEN_IF) {
  492. return TRUE;
  493. }
  494. return FALSE;
  495. }
  496. BOOLEAN
  497. NtCreateFileHandler(
  498. PPROCESS_INFO Process,
  499. PTHREAD_INFO Thread,
  500. PAPI_SAVED_PARAMETERS Parameters
  501. )
  502. {
  503. PCREATEFILE_PARAMETERS p = &Parameters->InputParameters.CreateFile;
  504. BOOLEAN Result;
  505. if (!Parameters->ReturnValueValid) {
  506. Result = CaptureOpenState( Process,
  507. Parameters,
  508. p->ObjectAttributes,
  509. IsFileWriteAccessRequested( p->DesiredAccess, p->CreateDisposition ),
  510. p->FileHandle,
  511. HANDLE_TYPE_FILE
  512. );
  513. if (Result
  514. // && Parameters->SavedCallState.PathOpen.WriteAccessRequested
  515. ) {
  516. DbgEvent( CREATEEVENT, ( "NtCreateFile called:\n"
  517. " Name: %ws\n"
  518. " Access: %s\n"
  519. " Share: %s\n"
  520. " Create: %s\n"
  521. " Options:%s\n",
  522. Parameters->SavedCallState.FullName,
  523. FormatEnumType( 0,
  524. FileAccessNames,
  525. p->DesiredAccess,
  526. TRUE
  527. ),
  528. FormatEnumType( 1,
  529. FileShareNames,
  530. p->ShareAccess,
  531. TRUE
  532. ),
  533. FormatEnumType( 2,
  534. FileCreateDispositionNames,
  535. p->CreateDisposition,
  536. FALSE
  537. ),
  538. FormatEnumType( 3,
  539. FileCreateOptionNames,
  540. p->CreateOptions,
  541. TRUE
  542. )
  543. )
  544. );
  545. }
  546. }
  547. else {
  548. Result = CompleteOpenState( Process,
  549. Parameters
  550. );
  551. if (Result
  552. // && Parameters->SavedCallState.PathOpen.WriteAccessRequested
  553. ) {
  554. IO_STATUS_BLOCK IoStatusBlock;
  555. ReadMemory( Process,
  556. p->IoStatusBlock,
  557. &IoStatusBlock,
  558. sizeof( IoStatusBlock ),
  559. "IoStatusBlock"
  560. );
  561. DbgEvent( CREATEEVENT, ( "*** Returned %s [%s %s]\n",
  562. FormatEnumType( 0,
  563. (PENUM_TYPE_NAMES)ntstatusSymbolicNames,
  564. Parameters->ReturnValue.ReturnedLong,
  565. FALSE
  566. ),
  567. FormatEnumType( 1,
  568. (PENUM_TYPE_NAMES)ntstatusSymbolicNames,
  569. IoStatusBlock.Status,
  570. FALSE
  571. ),
  572. FormatEnumType( 2,
  573. FileIoStatusInfoNames,
  574. IoStatusBlock.Information,
  575. FALSE
  576. )
  577. )
  578. );
  579. }
  580. }
  581. return Result;
  582. }
  583. BOOLEAN
  584. NtOpenFileHandler(
  585. PPROCESS_INFO Process,
  586. PTHREAD_INFO Thread,
  587. PAPI_SAVED_PARAMETERS Parameters
  588. )
  589. {
  590. POPENFILE_PARAMETERS p = &Parameters->InputParameters.OpenFile;
  591. BOOLEAN Result;
  592. if (!Parameters->ReturnValueValid) {
  593. Result = CaptureOpenState( Process,
  594. Parameters,
  595. p->ObjectAttributes,
  596. IsFileWriteAccessRequested( p->DesiredAccess, FILE_OPEN ),
  597. p->FileHandle,
  598. HANDLE_TYPE_FILE
  599. );
  600. if (Result
  601. // && Parameters->SavedCallState.PathOpen.WriteAccessRequested
  602. ) {
  603. DbgEvent( CREATEEVENT, ( "NtOpenFile called:\n"
  604. " Name: %ws\n"
  605. " Access: %s\n"
  606. " Share: %s\n"
  607. " Options:%s\n",
  608. Parameters->SavedCallState.FullName,
  609. FormatEnumType( 0,
  610. FileAccessNames,
  611. p->DesiredAccess,
  612. TRUE
  613. ),
  614. FormatEnumType( 1,
  615. FileShareNames,
  616. p->ShareAccess,
  617. TRUE
  618. ),
  619. FormatEnumType( 2,
  620. FileCreateOptionNames,
  621. p->OpenOptions,
  622. TRUE
  623. )
  624. )
  625. );
  626. }
  627. }
  628. else {
  629. Result = CompleteOpenState( Process,
  630. Parameters
  631. );
  632. if (Result
  633. // && Parameters->SavedCallState.PathOpen.WriteAccessRequested
  634. ) {
  635. IO_STATUS_BLOCK IoStatusBlock;
  636. ReadMemory( Process,
  637. p->IoStatusBlock,
  638. &IoStatusBlock,
  639. sizeof( IoStatusBlock ),
  640. "IoStatusBlock"
  641. );
  642. DbgEvent( CREATEEVENT, ( "*** Returned %s [%s %s]\n",
  643. FormatEnumType( 0,
  644. (PENUM_TYPE_NAMES)ntstatusSymbolicNames,
  645. Parameters->ReturnValue.ReturnedLong,
  646. FALSE
  647. ),
  648. FormatEnumType( 1,
  649. (PENUM_TYPE_NAMES)ntstatusSymbolicNames,
  650. IoStatusBlock.Status,
  651. FALSE
  652. ),
  653. FormatEnumType( 2,
  654. FileIoStatusInfoNames,
  655. IoStatusBlock.Information,
  656. FALSE
  657. )
  658. )
  659. );
  660. }
  661. }
  662. return Result;
  663. }
  664. BOOLEAN
  665. NtDeleteFileHandler(
  666. PPROCESS_INFO Process,
  667. PTHREAD_INFO Thread,
  668. PAPI_SAVED_PARAMETERS Parameters
  669. )
  670. {
  671. PDELETEFILE_PARAMETERS p = &Parameters->InputParameters.DeleteFile;
  672. OBJECT_ATTRIBUTES ObjectAttributes;
  673. UNICODE_STRING ObjectName;
  674. PWSTR FullName;
  675. BOOLEAN Result, CallSuccessful;
  676. PFILE_REFERENCE FileReference;
  677. if (!Parameters->ReturnValueValid) {
  678. if (CaptureObjectAttributes( Process,
  679. p->ObjectAttributes,
  680. &ObjectAttributes,
  681. &ObjectName
  682. ) &&
  683. CaptureFullName( Process,
  684. HANDLE_TYPE_FILE,
  685. ObjectAttributes.RootDirectory,
  686. ObjectName.Buffer,
  687. ObjectName.Length,
  688. &FullName
  689. ) &&
  690. CreateSavedCallState( Process,
  691. &Parameters->SavedCallState,
  692. DeletePath,
  693. HANDLE_TYPE_FILE,
  694. FullName
  695. )
  696. ) {
  697. Result = CreateFileReference( FullName,
  698. TRUE,
  699. (PFILE_REFERENCE *)&Parameters->SavedCallState.Reference
  700. );
  701. }
  702. else {
  703. Result = FALSE;
  704. }
  705. return Result;
  706. }
  707. else {
  708. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong )) {
  709. CallSuccessful = TRUE;
  710. }
  711. else {
  712. CallSuccessful = FALSE;
  713. }
  714. FileReference = (PFILE_REFERENCE)Parameters->SavedCallState.Reference;
  715. CompleteFileReference( FileReference,
  716. CallSuccessful,
  717. TRUE,
  718. NULL
  719. );
  720. return TRUE;
  721. }
  722. }
  723. #undef DeleteFile
  724. BOOLEAN
  725. NtSetInformationFileHandler(
  726. PPROCESS_INFO Process,
  727. PTHREAD_INFO Thread,
  728. PAPI_SAVED_PARAMETERS Parameters
  729. )
  730. {
  731. PSETINFORMATIONFILE_PARAMETERS p = &Parameters->InputParameters.SetInformationFile;
  732. POPENHANDLE_INFO HandleInfo;
  733. FILE_RENAME_INFORMATION RenameInformation;
  734. FILE_DISPOSITION_INFORMATION DispositionInformation;
  735. PWSTR NewName, OldName;
  736. PFILE_REFERENCE OldFileReference;
  737. PFILE_REFERENCE NewFileReference;
  738. BOOLEAN Result, CallSuccessful;
  739. HandleInfo = FindOpenHandle( Process,
  740. p->FileHandle,
  741. HANDLE_TYPE_FILE
  742. );
  743. if (HandleInfo == NULL) {
  744. Result = FALSE;
  745. }
  746. else
  747. if (p->FileInformationClass == FileRenameInformation) {
  748. //
  749. // Renaming an open file.
  750. //
  751. if (!Parameters->ReturnValueValid) {
  752. if (ReadMemory( Process,
  753. p->FileInformation,
  754. &RenameInformation,
  755. FIELD_OFFSET( FILE_RENAME_INFORMATION, FileName ),
  756. "rename information"
  757. ) &&
  758. CaptureFullName( Process,
  759. HANDLE_TYPE_FILE,
  760. RenameInformation.RootDirectory,
  761. &((PFILE_RENAME_INFORMATION)(p->FileInformation))->FileName[ 0 ],
  762. RenameInformation.FileNameLength,
  763. &NewName
  764. ) &&
  765. CreateSavedCallState( Process,
  766. &Parameters->SavedCallState,
  767. RenamePath,
  768. HANDLE_TYPE_FILE,
  769. HandleInfo->Name,
  770. NewName,
  771. RenameInformation.ReplaceIfExists
  772. )
  773. ) {
  774. Result = CreateFileReference( NewName,
  775. RenameInformation.ReplaceIfExists,
  776. (PFILE_REFERENCE *)&Parameters->SavedCallState.Reference
  777. );
  778. }
  779. else {
  780. Result = FALSE;
  781. }
  782. }
  783. else {
  784. OldName = NULL;
  785. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong )) {
  786. CallSuccessful = TRUE;
  787. OldFileReference = FindFileReference( HandleInfo->Name );
  788. if (OldFileReference) {
  789. OldName = OldFileReference->Name;
  790. }
  791. }
  792. else {
  793. CallSuccessful = FALSE;
  794. OldFileReference = NULL;
  795. }
  796. NewFileReference = (PFILE_REFERENCE)Parameters->SavedCallState.Reference;
  797. NewName = NewFileReference->Name;
  798. CompleteFileReference( NewFileReference,
  799. CallSuccessful,
  800. (BOOLEAN)(!NewFileReference->Created),
  801. OldFileReference
  802. );
  803. Result = TRUE;
  804. }
  805. }
  806. else
  807. if (p->FileInformationClass == FileDispositionInformation) {
  808. //
  809. // Marking an open file for delete.
  810. //
  811. if (!Parameters->ReturnValueValid) {
  812. if (ReadMemory( Process,
  813. p->FileInformation,
  814. &DispositionInformation,
  815. sizeof( DispositionInformation ),
  816. "disposition information"
  817. ) &&
  818. DispositionInformation.DeleteFile &&
  819. CreateSavedCallState( Process,
  820. &Parameters->SavedCallState,
  821. DeletePath,
  822. HANDLE_TYPE_FILE,
  823. HandleInfo->Name
  824. )
  825. ) {
  826. Result = TRUE;
  827. }
  828. else {
  829. Result = FALSE;
  830. }
  831. }
  832. else {
  833. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong )) {
  834. if (OldFileReference = FindFileReference( HandleInfo->Name )) {
  835. if (OldFileReference->Created) {
  836. LogEvent( INSTALER_EVENT_DELETE_TEMP_FILE,
  837. 2,
  838. OldFileReference->DirectoryFile ? L"directory" : L"file",
  839. OldFileReference->Name
  840. );
  841. DestroyFileReference( OldFileReference );
  842. }
  843. else {
  844. OldFileReference->Deleted = TRUE;
  845. LogEvent( INSTALER_EVENT_DELETE_FILE,
  846. 2,
  847. OldFileReference->DirectoryFile ? L"directory" : L"file",
  848. OldFileReference->Name
  849. );
  850. }
  851. }
  852. }
  853. Result = TRUE;
  854. }
  855. }
  856. else {
  857. Result = FALSE;
  858. }
  859. return Result;
  860. }
  861. BOOLEAN
  862. CaptureUnicodeString(
  863. PPROCESS_INFO Process,
  864. PUNICODE_STRING UnicodeStringAddress,
  865. PWSTR *ReturnedString
  866. )
  867. {
  868. UNICODE_STRING UnicodeString;
  869. PWSTR s;
  870. s = NULL;
  871. if (ReadMemory( Process,
  872. UnicodeStringAddress,
  873. &UnicodeString,
  874. sizeof( UnicodeString ),
  875. "unicode string"
  876. ) &&
  877. ((s = AllocMem( UnicodeString.Length + sizeof( UNICODE_NULL ) )) != NULL) &&
  878. ReadMemory( Process,
  879. UnicodeString.Buffer,
  880. s,
  881. UnicodeString.Length,
  882. "unicode string buffer"
  883. )
  884. ) {
  885. *ReturnedString = s;
  886. return TRUE;
  887. }
  888. FreeMem( &s );
  889. return FALSE;
  890. }
  891. BOOLEAN
  892. NtQueryAttributesFileHandler(
  893. PPROCESS_INFO Process,
  894. PTHREAD_INFO Thread,
  895. PAPI_SAVED_PARAMETERS Parameters
  896. )
  897. {
  898. PQUERYATTRIBUTESFILE_PARAMETERS p = &Parameters->InputParameters.QueryAttributesFile;
  899. OBJECT_ATTRIBUTES ObjectAttributes;
  900. UNICODE_STRING ObjectName;
  901. PWSTR FullName;
  902. NTSTATUS Status;
  903. BOOLEAN Result;
  904. CHAR Buffer[ MAX_PATH ];
  905. if (!Parameters->ReturnValueValid) {
  906. FullName = NULL;
  907. Result = FALSE;
  908. if (CaptureObjectAttributes( Process,
  909. p->ObjectAttributes,
  910. &ObjectAttributes,
  911. &ObjectName
  912. ) &&
  913. CaptureFullName( Process,
  914. HANDLE_TYPE_FILE,
  915. ObjectAttributes.RootDirectory,
  916. ObjectName.Buffer,
  917. ObjectName.Length,
  918. &FullName
  919. ) &&
  920. CreateSavedCallState( Process,
  921. &Parameters->SavedCallState,
  922. QueryPath,
  923. HANDLE_TYPE_FILE,
  924. FullName
  925. )
  926. ) {
  927. Result = CreateFileReference( FullName,
  928. FALSE,
  929. (PFILE_REFERENCE *)&Parameters->SavedCallState.Reference
  930. );
  931. }
  932. else {
  933. Result = FALSE;
  934. }
  935. return Result;
  936. }
  937. else {
  938. FILE_BASIC_INFORMATION FileInformation;
  939. ReadMemory( Process,
  940. p->FileInformation,
  941. &FileInformation,
  942. sizeof( FileInformation ),
  943. "FileInformation"
  944. );
  945. return TRUE;
  946. }
  947. }
  948. BOOLEAN
  949. NtQueryDirectoryFileHandler(
  950. PPROCESS_INFO Process,
  951. PTHREAD_INFO Thread,
  952. PAPI_SAVED_PARAMETERS Parameters
  953. )
  954. {
  955. PQUERYDIRECTORYFILE_PARAMETERS p = &Parameters->InputParameters.QueryDirectoryFile;
  956. POPENHANDLE_INFO HandleInfo;
  957. PWSTR FileName;
  958. NTSTATUS Status;
  959. BOOLEAN Result;
  960. PULONG pNextEntryOffset;
  961. ULONG NextEntryOffset;
  962. ULONG EntriesReturned;
  963. if (!Parameters->ReturnValueValid) {
  964. FileName = NULL;
  965. Result = FALSE;
  966. if ((HandleInfo = FindOpenHandle( Process,
  967. p->FileHandle,
  968. HANDLE_TYPE_FILE
  969. )
  970. ) != NULL &&
  971. p->FileName != NULL &&
  972. CaptureUnicodeString( Process,
  973. p->FileName,
  974. &FileName
  975. )
  976. ) {
  977. if (HandleInfo->RootDirectory &&
  978. !wcscmp( FileName, L"*" ) || !wcscmp( FileName, L"*.*" )
  979. ) {
  980. if (AskUserOnce) {
  981. AskUserOnce = FALSE;
  982. if (AskUser( MB_OKCANCEL,
  983. INSTALER_ASKUSER_ROOTSCAN,
  984. 1,
  985. HandleInfo->Name
  986. ) == IDCANCEL
  987. ) {
  988. FailAllScansOfRootDirectories = TRUE;
  989. }
  990. }
  991. Parameters->AbortCall = FailAllScansOfRootDirectories;
  992. }
  993. if (FileName) {
  994. HandleInfo->QueryName = FileName;
  995. }
  996. }
  997. return TRUE;
  998. }
  999. else {
  1000. if (Parameters->AbortCall) {
  1001. //
  1002. // If we get here, then user wanted to fail this call.
  1003. //
  1004. Status = STATUS_NO_MORE_FILES;
  1005. SetProcedureReturnValue( Process,
  1006. Thread,
  1007. &Status,
  1008. sizeof( Status )
  1009. );
  1010. return TRUE;
  1011. }
  1012. else {
  1013. if ((HandleInfo = FindOpenHandle( Process,
  1014. p->FileHandle,
  1015. HANDLE_TYPE_FILE
  1016. )
  1017. ) != NULL
  1018. ) {
  1019. //
  1020. // If successful, count entries returned
  1021. //
  1022. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong )) {
  1023. //
  1024. // Return buffer is a set of records, the first DWORD of each contains
  1025. // the offset to the next one or zero to indicate the end. Count them.
  1026. //
  1027. pNextEntryOffset = (PULONG)p->FileInformation;
  1028. EntriesReturned = 1;
  1029. while (ReadMemory( Process,
  1030. pNextEntryOffset,
  1031. &NextEntryOffset,
  1032. sizeof( NextEntryOffset ),
  1033. "DirectoryInformation"
  1034. ) &&
  1035. NextEntryOffset != 0
  1036. ) {
  1037. pNextEntryOffset = (PULONG)((PCHAR)pNextEntryOffset + NextEntryOffset);
  1038. EntriesReturned += 1;
  1039. }
  1040. LogEvent( INSTALER_EVENT_SCAN_DIRECTORY,
  1041. 3,
  1042. HandleInfo->Name,
  1043. HandleInfo->QueryName ? HandleInfo->QueryName : L"*",
  1044. EntriesReturned
  1045. );
  1046. }
  1047. else {
  1048. FreeMem( &HandleInfo->QueryName );
  1049. }
  1050. }
  1051. }
  1052. return TRUE;
  1053. }
  1054. }
  1055. BOOLEAN
  1056. IsKeyWriteAccessRequested(
  1057. ACCESS_MASK DesiredAccess
  1058. )
  1059. {
  1060. if (DesiredAccess & (GENERIC_WRITE |
  1061. GENERIC_ALL |
  1062. DELETE |
  1063. KEY_SET_VALUE |
  1064. KEY_CREATE_SUB_KEY |
  1065. KEY_CREATE_LINK
  1066. )
  1067. ) {
  1068. return TRUE;
  1069. }
  1070. return FALSE;
  1071. }
  1072. BOOLEAN
  1073. NtCreateKeyHandler(
  1074. PPROCESS_INFO Process,
  1075. PTHREAD_INFO Thread,
  1076. PAPI_SAVED_PARAMETERS Parameters
  1077. )
  1078. {
  1079. PCREATEKEY_PARAMETERS p = &Parameters->InputParameters.CreateKey;
  1080. BOOLEAN Result;
  1081. if (!Parameters->ReturnValueValid) {
  1082. Result = CaptureOpenState( Process,
  1083. Parameters,
  1084. p->ObjectAttributes,
  1085. IsKeyWriteAccessRequested( p->DesiredAccess ),
  1086. p->KeyHandle,
  1087. HANDLE_TYPE_KEY
  1088. );
  1089. }
  1090. else {
  1091. Result = CompleteOpenState( Process,
  1092. Parameters
  1093. );
  1094. }
  1095. return Result;
  1096. }
  1097. BOOLEAN
  1098. NtOpenKeyHandler(
  1099. PPROCESS_INFO Process,
  1100. PTHREAD_INFO Thread,
  1101. PAPI_SAVED_PARAMETERS Parameters
  1102. )
  1103. {
  1104. POPENKEY_PARAMETERS p = &Parameters->InputParameters.OpenKey;
  1105. BOOLEAN Result;
  1106. if (!Parameters->ReturnValueValid) {
  1107. Result = CaptureOpenState( Process,
  1108. Parameters,
  1109. p->ObjectAttributes,
  1110. IsKeyWriteAccessRequested( p->DesiredAccess ),
  1111. p->KeyHandle,
  1112. HANDLE_TYPE_KEY
  1113. );
  1114. }
  1115. else {
  1116. Result = CompleteOpenState( Process,
  1117. Parameters
  1118. );
  1119. }
  1120. return Result;
  1121. }
  1122. BOOLEAN
  1123. NtDeleteKeyHandler(
  1124. PPROCESS_INFO Process,
  1125. PTHREAD_INFO Thread,
  1126. PAPI_SAVED_PARAMETERS Parameters
  1127. )
  1128. {
  1129. PDELETEKEY_PARAMETERS p = &Parameters->InputParameters.DeleteKey;
  1130. POPENHANDLE_INFO HandleInfo;
  1131. PKEY_REFERENCE OldKeyReference;
  1132. BOOLEAN Result;
  1133. //
  1134. // Marking an open key for delete.
  1135. //
  1136. HandleInfo = FindOpenHandle( Process,
  1137. p->KeyHandle,
  1138. HANDLE_TYPE_KEY
  1139. );
  1140. if (HandleInfo == NULL) {
  1141. Result = FALSE;
  1142. }
  1143. else
  1144. if (!Parameters->ReturnValueValid) {
  1145. if (CreateSavedCallState( Process,
  1146. &Parameters->SavedCallState,
  1147. DeletePath,
  1148. HANDLE_TYPE_KEY,
  1149. HandleInfo->Name
  1150. )
  1151. ) {
  1152. Result = TRUE;
  1153. }
  1154. else {
  1155. Result = FALSE;
  1156. }
  1157. }
  1158. else {
  1159. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong )) {
  1160. if (OldKeyReference = FindKeyReference( HandleInfo->Name )) {
  1161. if (OldKeyReference->Created) {
  1162. LogEvent( INSTALER_EVENT_DELETE_TEMP_KEY,
  1163. 1,
  1164. OldKeyReference->Name
  1165. );
  1166. DestroyKeyReference( OldKeyReference );
  1167. }
  1168. else {
  1169. MarkKeyDeleted( OldKeyReference );
  1170. LogEvent( INSTALER_EVENT_DELETE_KEY,
  1171. 1,
  1172. OldKeyReference->Name
  1173. );
  1174. }
  1175. }
  1176. }
  1177. Result = TRUE;
  1178. }
  1179. return Result;
  1180. }
  1181. BOOLEAN
  1182. CaptureValueName(
  1183. PPROCESS_INFO Process,
  1184. PUNICODE_STRING Name,
  1185. PWSTR *ReturnedValueName
  1186. )
  1187. {
  1188. UNICODE_STRING ValueName;
  1189. PWSTR s;
  1190. *ReturnedValueName = NULL;
  1191. if (Name == NULL ||
  1192. !ReadMemory( Process,
  1193. Name,
  1194. &ValueName,
  1195. sizeof( ValueName ),
  1196. "value name string"
  1197. )
  1198. ) {
  1199. return FALSE;
  1200. }
  1201. s = AllocMem( ValueName.Length + sizeof( UNICODE_NULL ) );
  1202. if (s == NULL) {
  1203. return FALSE;
  1204. }
  1205. if (!ReadMemory( Process,
  1206. ValueName.Buffer,
  1207. s,
  1208. ValueName.Length,
  1209. "value name buffer"
  1210. )
  1211. ) {
  1212. FreeMem( &s );
  1213. return FALSE;
  1214. }
  1215. s[ ValueName.Length / sizeof( WCHAR ) ] = UNICODE_NULL;
  1216. ValueName.Buffer = s;
  1217. ValueName.MaximumLength = (USHORT)(ValueName.Length + sizeof( UNICODE_NULL ));
  1218. *ReturnedValueName = AddName( &ValueName );
  1219. FreeMem( &ValueName.Buffer );
  1220. return TRUE;
  1221. }
  1222. BOOLEAN
  1223. NtSetValueKeyHandler(
  1224. PPROCESS_INFO Process,
  1225. PTHREAD_INFO Thread,
  1226. PAPI_SAVED_PARAMETERS Parameters
  1227. )
  1228. {
  1229. PSETVALUEKEY_PARAMETERS p = &Parameters->InputParameters.SetValueKey;
  1230. POPENHANDLE_INFO HandleInfo;
  1231. PWSTR ValueName;
  1232. PKEY_REFERENCE KeyReference;
  1233. PVALUE_REFERENCE ValueReference;
  1234. BOOLEAN Result;
  1235. //
  1236. // Setting a value
  1237. //
  1238. HandleInfo = FindOpenHandle( Process,
  1239. p->KeyHandle,
  1240. HANDLE_TYPE_KEY
  1241. );
  1242. if (HandleInfo == NULL) {
  1243. Result = FALSE;
  1244. }
  1245. else
  1246. if (!Parameters->ReturnValueValid) {
  1247. if (CaptureValueName( Process,
  1248. p->ValueName,
  1249. &ValueName
  1250. ) &&
  1251. CreateSavedCallState( Process,
  1252. &Parameters->SavedCallState,
  1253. SetValue,
  1254. HANDLE_TYPE_KEY,
  1255. ValueName
  1256. )
  1257. ) {
  1258. Result = TRUE;
  1259. }
  1260. else {
  1261. Result = FALSE;
  1262. }
  1263. }
  1264. else {
  1265. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong ) &&
  1266. (KeyReference = FindKeyReference( HandleInfo->Name ))
  1267. ) {
  1268. CreateValueReference( Process,
  1269. KeyReference,
  1270. Parameters->SavedCallState.FullName,
  1271. p->TitleIndex,
  1272. p->Type,
  1273. p->Data,
  1274. p->DataLength,
  1275. &ValueReference
  1276. );
  1277. if (ValueReference != NULL) {
  1278. LogEvent( INSTALER_EVENT_SET_KEY_VALUE,
  1279. 2,
  1280. ValueReference->Name,
  1281. KeyReference->Name
  1282. );
  1283. }
  1284. }
  1285. Result = TRUE;
  1286. }
  1287. return Result;
  1288. }
  1289. BOOLEAN
  1290. NtDeleteValueKeyHandler(
  1291. PPROCESS_INFO Process,
  1292. PTHREAD_INFO Thread,
  1293. PAPI_SAVED_PARAMETERS Parameters
  1294. )
  1295. {
  1296. PDELETEVALUEKEY_PARAMETERS p = &Parameters->InputParameters.DeleteValueKey;
  1297. POPENHANDLE_INFO HandleInfo;
  1298. PWSTR ValueName;
  1299. PKEY_REFERENCE KeyReference;
  1300. PVALUE_REFERENCE ValueReference;
  1301. BOOLEAN Result;
  1302. //
  1303. // Marking a value for delete.
  1304. //
  1305. HandleInfo = FindOpenHandle( Process,
  1306. p->KeyHandle,
  1307. HANDLE_TYPE_KEY
  1308. );
  1309. if (HandleInfo == NULL) {
  1310. Result = FALSE;
  1311. }
  1312. else
  1313. if (!Parameters->ReturnValueValid) {
  1314. if (CaptureValueName( Process,
  1315. p->ValueName,
  1316. &ValueName
  1317. ) &&
  1318. CreateSavedCallState( Process,
  1319. &Parameters->SavedCallState,
  1320. DeleteValue,
  1321. HANDLE_TYPE_KEY,
  1322. ValueName
  1323. )
  1324. ) {
  1325. Result = TRUE;
  1326. }
  1327. else {
  1328. Result = FALSE;
  1329. }
  1330. }
  1331. else {
  1332. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong ) &&
  1333. (KeyReference = FindKeyReference( HandleInfo->Name )) &&
  1334. (ValueReference = FindValueReference( KeyReference, Parameters->SavedCallState.FullName ))
  1335. ) {
  1336. if (ValueReference->Created) {
  1337. LogEvent( INSTALER_EVENT_DELETE_KEY_TEMP_VALUE,
  1338. 2,
  1339. ValueReference->Name,
  1340. KeyReference->Name
  1341. );
  1342. DestroyValueReference( ValueReference );
  1343. }
  1344. else {
  1345. ValueReference->Deleted = TRUE;
  1346. LogEvent( INSTALER_EVENT_DELETE_KEY_VALUE,
  1347. 2,
  1348. ValueReference->Name,
  1349. KeyReference->Name
  1350. );
  1351. }
  1352. }
  1353. Result = TRUE;
  1354. }
  1355. return Result;
  1356. }
  1357. BOOLEAN
  1358. NtCloseHandleHandler(
  1359. PPROCESS_INFO Process,
  1360. PTHREAD_INFO Thread,
  1361. PAPI_SAVED_PARAMETERS Parameters
  1362. )
  1363. {
  1364. PCLOSEHANDLE_PARAMETERS p = &Parameters->InputParameters.CloseHandle;
  1365. POPENHANDLE_INFO HandleInfo;
  1366. PFILE_REFERENCE FileReference;
  1367. HandleInfo = FindOpenHandle( Process, p->Handle, (ULONG)-1 );
  1368. if (!Parameters->ReturnValueValid) {
  1369. if (HandleInfo != NULL) {
  1370. return TRUE;
  1371. }
  1372. else {
  1373. return FALSE;
  1374. }
  1375. }
  1376. else {
  1377. if (NT_SUCCESS( Parameters->ReturnValue.ReturnedLong )) {
  1378. if (HandleInfo != NULL &&
  1379. HandleInfo->Type == HANDLE_TYPE_FILE &&
  1380. (FileReference = FindFileReference( HandleInfo->Name )) != NULL &&
  1381. FileReference->WriteAccess &&
  1382. !FileReference->Created &&
  1383. !FileReference->DirectoryFile &&
  1384. IsNewFileSameAsBackup( FileReference )
  1385. ) {
  1386. DestroyFileReference( FileReference );
  1387. FileReference = NULL;
  1388. }
  1389. DeleteOpenHandle( Process, p->Handle, (ULONG)-1 );
  1390. }
  1391. return TRUE;
  1392. }
  1393. }
  1394. UCHAR AnsiStringBuffer[ MAX_PATH+1 ];
  1395. WCHAR UnicodeStringBuffer[ MAX_PATH+1 ];
  1396. BOOLEAN
  1397. CaptureAnsiAsUnicode(
  1398. PPROCESS_INFO Process,
  1399. LPCSTR Address,
  1400. BOOLEAN DoubleNullTermination,
  1401. PWSTR *ReturnedName,
  1402. PWSTR *ReturnedData
  1403. )
  1404. {
  1405. NTSTATUS Status;
  1406. ULONG BytesRead;
  1407. ANSI_STRING AnsiString;
  1408. UNICODE_STRING UnicodeString;
  1409. if (Address == NULL) {
  1410. if (ReturnedName != NULL) {
  1411. *ReturnedName = NULL;
  1412. }
  1413. else {
  1414. *ReturnedData = NULL;
  1415. }
  1416. return TRUE;
  1417. }
  1418. BytesRead = FillTemporaryBuffer( Process,
  1419. (PVOID)Address,
  1420. FALSE,
  1421. DoubleNullTermination
  1422. );
  1423. if (BytesRead != 0 && BytesRead < 0x7FFF) {
  1424. AnsiString.Buffer = TemporaryBuffer;
  1425. AnsiString.Length = (USHORT)BytesRead;
  1426. AnsiString.MaximumLength = (USHORT)BytesRead;
  1427. Status = RtlAnsiStringToUnicodeString( &UnicodeString, &AnsiString, TRUE );
  1428. if (NT_SUCCESS( Status )) {
  1429. if (ReturnedName != NULL) {
  1430. *ReturnedName = AddName( &UnicodeString );
  1431. RtlFreeUnicodeString( &UnicodeString );
  1432. return TRUE;
  1433. }
  1434. else {
  1435. *ReturnedData = UnicodeString.Buffer;
  1436. return TRUE;
  1437. }
  1438. }
  1439. }
  1440. return FALSE;
  1441. }
  1442. BOOLEAN
  1443. CaptureUnicode(
  1444. PPROCESS_INFO Process,
  1445. LPCWSTR Address,
  1446. BOOLEAN DoubleNullTermination,
  1447. PWSTR *ReturnedName,
  1448. PWSTR *ReturnedData
  1449. )
  1450. {
  1451. ULONG BytesRead;
  1452. UNICODE_STRING UnicodeString;
  1453. if (Address == NULL) {
  1454. if (ReturnedName != NULL) {
  1455. *ReturnedName = NULL;
  1456. }
  1457. else {
  1458. *ReturnedData = NULL;
  1459. }
  1460. return TRUE;
  1461. }
  1462. BytesRead = FillTemporaryBuffer( Process,
  1463. (PVOID)Address,
  1464. TRUE,
  1465. DoubleNullTermination
  1466. );
  1467. if (BytesRead != 0 && (BytesRead & 1) == 0 && BytesRead <= 0xFFFC) {
  1468. if (ReturnedName != NULL) {
  1469. RtlInitUnicodeString( &UnicodeString, TemporaryBuffer );
  1470. *ReturnedName = AddName( &UnicodeString );
  1471. return TRUE;
  1472. }
  1473. else {
  1474. *ReturnedData = AllocMem( BytesRead + sizeof( UNICODE_NULL ) );
  1475. if (*ReturnedData != NULL) {
  1476. memmove( *ReturnedData, TemporaryBuffer, BytesRead );
  1477. return TRUE;
  1478. }
  1479. }
  1480. }
  1481. return FALSE;
  1482. }
  1483. BOOLEAN
  1484. GetVersionHandler(
  1485. PPROCESS_INFO Process,
  1486. PTHREAD_INFO Thread,
  1487. PAPI_SAVED_PARAMETERS Parameters
  1488. )
  1489. {
  1490. DWORD dwVersion;
  1491. if (!Parameters->ReturnValueValid) {
  1492. if (AskUserOnce) {
  1493. AskUserOnce = FALSE;
  1494. if (AskUser( MB_OKCANCEL,
  1495. INSTALER_ASKUSER_GETVERSION,
  1496. 0
  1497. ) == IDCANCEL
  1498. ) {
  1499. DefaultGetVersionToWin95 = TRUE;
  1500. }
  1501. else {
  1502. DefaultGetVersionToWin95 = FALSE;
  1503. }
  1504. }
  1505. LogEvent( INSTALER_EVENT_GETVERSION,
  1506. 1,
  1507. DefaultGetVersionToWin95 ? L"Windows 95" : L"Windows NT"
  1508. );
  1509. Parameters->AbortCall = DefaultGetVersionToWin95;
  1510. return Parameters->AbortCall;
  1511. }
  1512. else {
  1513. dwVersion = 0xC0000004; // What Windows 95 returns
  1514. SetProcedureReturnValue( Process,
  1515. Thread,
  1516. &dwVersion,
  1517. sizeof( dwVersion )
  1518. );
  1519. return TRUE;
  1520. }
  1521. }
  1522. BOOLEAN
  1523. GetVersionExWHandler(
  1524. PPROCESS_INFO Process,
  1525. PTHREAD_INFO Thread,
  1526. PAPI_SAVED_PARAMETERS Parameters
  1527. )
  1528. {
  1529. PGETVERSIONEXW_PARAMETERS p = &Parameters->InputParameters.GetVersionExW;
  1530. OSVERSIONINFOW VersionInformation;
  1531. if (!Parameters->ReturnValueValid) {
  1532. if (AskUserOnce) {
  1533. AskUserOnce = FALSE;
  1534. if (AskUser( MB_OKCANCEL,
  1535. INSTALER_ASKUSER_GETVERSION,
  1536. 0
  1537. ) == IDCANCEL
  1538. ) {
  1539. DefaultGetVersionToWin95 = TRUE;
  1540. }
  1541. else {
  1542. DefaultGetVersionToWin95 = FALSE;
  1543. }
  1544. }
  1545. Parameters->AbortCall = DefaultGetVersionToWin95;
  1546. return Parameters->AbortCall;
  1547. }
  1548. else {
  1549. memset( &VersionInformation, 0, sizeof( VersionInformation ) );
  1550. VersionInformation.dwMajorVersion = 4;
  1551. VersionInformation.dwBuildNumber = 0x3B6; // What Windows 95 returns
  1552. VersionInformation.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
  1553. WriteMemory( Process,
  1554. p->lpVersionInformation,
  1555. &VersionInformation,
  1556. sizeof( VersionInformation ),
  1557. "GetVersionExW"
  1558. );
  1559. return TRUE;
  1560. }
  1561. }
  1562. BOOLEAN
  1563. SetCurrentDirectoryAHandler(
  1564. PPROCESS_INFO Process,
  1565. PTHREAD_INFO Thread,
  1566. PAPI_SAVED_PARAMETERS Parameters
  1567. )
  1568. {
  1569. PSETCURRENTDIRECTORYA_PARAMETERS p = &Parameters->InputParameters.SetCurrentDirectoryA;
  1570. PWSTR PathName;
  1571. WCHAR PathBuffer[ MAX_PATH ];
  1572. if (!Parameters->ReturnValueValid) {
  1573. if (CaptureAnsiAsUnicode( Process, p->lpPathName, FALSE, NULL, &PathName ) && PathName != NULL) {
  1574. Parameters->CurrentDirectory = AllocMem( (wcslen( PathName ) + 1) * sizeof( WCHAR ) );
  1575. if (Parameters->CurrentDirectory != NULL) {
  1576. wcscpy( Parameters->CurrentDirectory, PathName );
  1577. return TRUE;
  1578. }
  1579. }
  1580. return FALSE;
  1581. }
  1582. else {
  1583. if (Parameters->ReturnValue.ReturnedBool != 0) {
  1584. if (SetCurrentDirectory( Parameters->CurrentDirectory ) &&
  1585. GetCurrentDirectory( MAX_PATH, PathBuffer )
  1586. ) {
  1587. LogEvent( INSTALER_EVENT_SET_DIRECTORY,
  1588. 1,
  1589. PathBuffer
  1590. );
  1591. }
  1592. }
  1593. FreeMem( &Parameters->CurrentDirectory );
  1594. return TRUE;
  1595. }
  1596. }
  1597. BOOLEAN
  1598. SetCurrentDirectoryWHandler(
  1599. PPROCESS_INFO Process,
  1600. PTHREAD_INFO Thread,
  1601. PAPI_SAVED_PARAMETERS Parameters
  1602. )
  1603. {
  1604. PSETCURRENTDIRECTORYW_PARAMETERS p = &Parameters->InputParameters.SetCurrentDirectoryW;
  1605. PWSTR PathName;
  1606. WCHAR PathBuffer[ MAX_PATH ];
  1607. if (!Parameters->ReturnValueValid) {
  1608. if (CaptureUnicode( Process, p->lpPathName, FALSE, NULL, &PathName ) && PathName != NULL) {
  1609. Parameters->CurrentDirectory = AllocMem( (wcslen( PathName ) + 1) * sizeof( WCHAR ) );
  1610. if (Parameters->CurrentDirectory != NULL) {
  1611. wcscpy( Parameters->CurrentDirectory, PathName );
  1612. return TRUE;
  1613. }
  1614. }
  1615. return FALSE;
  1616. }
  1617. else {
  1618. if (Parameters->ReturnValue.ReturnedBool != 0) {
  1619. if (SetCurrentDirectory( Parameters->CurrentDirectory ) &&
  1620. GetCurrentDirectory( MAX_PATH, PathBuffer )
  1621. ) {
  1622. LogEvent( INSTALER_EVENT_SET_DIRECTORY,
  1623. 1,
  1624. PathBuffer
  1625. );
  1626. }
  1627. }
  1628. FreeMem( &Parameters->CurrentDirectory );
  1629. return TRUE;
  1630. }
  1631. }
  1632. BOOLEAN
  1633. GetIniFilePath(
  1634. PWSTR IniFileName,
  1635. PWSTR *ReturnedIniFilePath
  1636. )
  1637. {
  1638. NTSTATUS Status;
  1639. UNICODE_STRING FileName, UnicodeString;
  1640. PWSTR FilePart;
  1641. DWORD n;
  1642. if (IniFileName == NULL) {
  1643. RtlInitUnicodeString( &FileName, L"win.ini" );
  1644. }
  1645. else {
  1646. RtlInitUnicodeString( &FileName, IniFileName );
  1647. }
  1648. if ((FileName.Length > sizeof( WCHAR ) &&
  1649. FileName.Buffer[ 1 ] == L':'
  1650. ) ||
  1651. (FileName.Length != 0 &&
  1652. wcscspn( FileName.Buffer, L"\\/" ) != (FileName.Length / sizeof( WCHAR ))
  1653. )
  1654. ) {
  1655. UnicodeString.MaximumLength = (USHORT)(MAX_PATH * sizeof( WCHAR ));
  1656. UnicodeString.Buffer = AllocMem( UnicodeString.MaximumLength );
  1657. if (UnicodeString.Buffer == NULL) {
  1658. Status = STATUS_NO_MEMORY;
  1659. }
  1660. else {
  1661. UnicodeString.Length = 0;
  1662. n = GetFullPathNameW( FileName.Buffer,
  1663. UnicodeString.MaximumLength / sizeof( WCHAR ),
  1664. UnicodeString.Buffer,
  1665. &FilePart
  1666. );
  1667. if (n > UnicodeString.MaximumLength) {
  1668. Status = STATUS_BUFFER_TOO_SMALL;
  1669. }
  1670. else {
  1671. UnicodeString.Length = (USHORT)(n * sizeof( WCHAR ));
  1672. Status = STATUS_SUCCESS;
  1673. }
  1674. }
  1675. }
  1676. else {
  1677. UnicodeString.Length = 0;
  1678. UnicodeString.MaximumLength = (USHORT)(WindowsDirectory.Length +
  1679. sizeof( WCHAR ) +
  1680. FileName.Length +
  1681. sizeof( UNICODE_NULL )
  1682. );
  1683. UnicodeString.Buffer = AllocMem( UnicodeString.MaximumLength );
  1684. if (UnicodeString.Buffer == NULL) {
  1685. Status = STATUS_NO_MEMORY;
  1686. }
  1687. else {
  1688. RtlCopyUnicodeString( &UnicodeString, &WindowsDirectory );
  1689. Status = RtlAppendUnicodeToString( &UnicodeString,
  1690. L"\\"
  1691. );
  1692. if (NT_SUCCESS( Status )) {
  1693. Status = RtlAppendUnicodeStringToString( &UnicodeString,
  1694. &FileName
  1695. );
  1696. }
  1697. }
  1698. }
  1699. if (IniFileName != NULL) {
  1700. FreeMem( &IniFileName );
  1701. }
  1702. if (NT_SUCCESS( Status )) {
  1703. *ReturnedIniFilePath = AddName( &UnicodeString );
  1704. FreeMem( &UnicodeString.Buffer );
  1705. return TRUE;
  1706. }
  1707. else {
  1708. FreeMem( &UnicodeString.Buffer );
  1709. return FALSE;
  1710. }
  1711. }
  1712. BOOLEAN
  1713. WritePrivateProfileStringEntry(
  1714. PPROCESS_INFO Process,
  1715. PTHREAD_INFO Thread,
  1716. PAPI_SAVED_PARAMETERS Parameters,
  1717. PWSTR IniFilePath,
  1718. PWSTR SectionName,
  1719. PWSTR VariableName,
  1720. PWSTR VariableValue
  1721. )
  1722. {
  1723. if (CreateSavedCallState( Process,
  1724. &Parameters->SavedCallState,
  1725. WriteIniValue,
  1726. HANDLE_TYPE_NONE,
  1727. IniFilePath,
  1728. SectionName,
  1729. VariableName,
  1730. VariableValue
  1731. ) &&
  1732. CreateIniFileReference( IniFilePath,
  1733. (PINI_FILE_REFERENCE *)&Parameters->SavedCallState.Reference
  1734. )
  1735. ) {
  1736. return TRUE;
  1737. }
  1738. else {
  1739. FreeMem( &VariableValue );
  1740. return FALSE;
  1741. }
  1742. }
  1743. BOOLEAN
  1744. WritePrivateProfileStringExit(
  1745. PPROCESS_INFO Process,
  1746. PTHREAD_INFO Thread,
  1747. PAPI_SAVED_PARAMETERS Parameters
  1748. )
  1749. {
  1750. PAPI_SAVED_CALL_STATE CallState;
  1751. PINI_FILE_REFERENCE IniFileReference;
  1752. PINI_SECTION_REFERENCE IniSectionReference;
  1753. PINI_VARIABLE_REFERENCE IniVariableReference;
  1754. if (Parameters->ReturnValue.ReturnedLong != 0) {
  1755. CallState = &Parameters->SavedCallState;
  1756. if (CallState->FullName == NULL &&
  1757. CallState->SetIniValue.SectionName == NULL &&
  1758. CallState->SetIniValue.VariableName == NULL
  1759. ) {
  1760. //
  1761. // Ignore calls to flush INI cache
  1762. //
  1763. return FALSE;
  1764. }
  1765. IniFileReference = FindIniFileReference( CallState->FullName );
  1766. if (IniFileReference == NULL) {
  1767. return TRUE;
  1768. }
  1769. IniSectionReference = FindIniSectionReference( IniFileReference,
  1770. CallState->SetIniValue.SectionName,
  1771. (BOOLEAN)(CallState->SetIniValue.VariableName != NULL)
  1772. );
  1773. if (IniSectionReference == NULL) {
  1774. return TRUE;
  1775. }
  1776. if (CallState->SetIniValue.VariableName == NULL) {
  1777. IniSectionReference->Deleted = TRUE;
  1778. LogEvent( INSTALER_EVENT_INI_DELETE_SECTION,
  1779. 2,
  1780. CallState->FullName,
  1781. CallState->SetIniValue.SectionName
  1782. );
  1783. } else {
  1784. IniVariableReference = FindIniVariableReference( IniSectionReference,
  1785. CallState->SetIniValue.VariableName,
  1786. (BOOLEAN)(CallState->SetIniValue.VariableValue != NULL)
  1787. );
  1788. if (IniVariableReference != NULL) {
  1789. if (CallState->SetIniValue.VariableValue != NULL) {
  1790. FreeMem( &IniVariableReference->Value );
  1791. IniVariableReference->Value = CallState->SetIniValue.VariableValue;
  1792. CallState->SetIniValue.VariableValue = NULL;
  1793. if (!IniVariableReference->Created) {
  1794. if (!wcscmp( IniVariableReference->Value,
  1795. IniVariableReference->OriginalValue
  1796. )
  1797. ) {
  1798. FreeMem( &IniVariableReference->Value );
  1799. } else {
  1800. IniVariableReference->Modified = TRUE;
  1801. LogEvent( INSTALER_EVENT_INI_CHANGE,
  1802. 5,
  1803. CallState->FullName,
  1804. CallState->SetIniValue.SectionName,
  1805. CallState->SetIniValue.VariableName,
  1806. IniVariableReference->Value,
  1807. IniVariableReference->OriginalValue
  1808. );
  1809. }
  1810. } else {
  1811. LogEvent( INSTALER_EVENT_INI_CREATE,
  1812. 4,
  1813. CallState->FullName,
  1814. CallState->SetIniValue.SectionName,
  1815. CallState->SetIniValue.VariableName,
  1816. IniVariableReference->Value
  1817. );
  1818. }
  1819. } else if (!IniVariableReference->Created) {
  1820. IniVariableReference->Deleted = TRUE;
  1821. LogEvent( INSTALER_EVENT_INI_DELETE,
  1822. 4,
  1823. CallState->FullName,
  1824. CallState->SetIniValue.SectionName,
  1825. CallState->SetIniValue.VariableName,
  1826. IniVariableReference->OriginalValue
  1827. );
  1828. } else {
  1829. DestroyIniVariableReference( IniVariableReference );
  1830. }
  1831. }
  1832. }
  1833. }
  1834. return TRUE;
  1835. }
  1836. BOOLEAN
  1837. WritePrivateProfileStringAHandler(
  1838. PPROCESS_INFO Process,
  1839. PTHREAD_INFO Thread,
  1840. PAPI_SAVED_PARAMETERS Parameters
  1841. )
  1842. {
  1843. PWRITEPRIVATEPROFILESTRINGA_PARAMETERS p = &Parameters->InputParameters.WritePrivateProfileStringA;
  1844. PWSTR SectionName, VariableName, FileName, VariableValue;
  1845. PWSTR IniFilePath;
  1846. if (!Parameters->ReturnValueValid) {
  1847. FileName = NULL;
  1848. VariableValue = NULL;
  1849. if (CaptureAnsiAsUnicode( Process, p->lpFileName, FALSE, NULL, &FileName ) &&
  1850. GetIniFilePath( FileName, &IniFilePath ) &&
  1851. CaptureAnsiAsUnicode( Process, p->lpAppName, FALSE, &SectionName, NULL ) &&
  1852. CaptureAnsiAsUnicode( Process, p->lpKeyName, FALSE, &VariableName, NULL ) &&
  1853. CaptureAnsiAsUnicode( Process, p->lpString, FALSE, NULL, &VariableValue )
  1854. ) {
  1855. if (FileName != NULL || SectionName != NULL) {
  1856. return WritePrivateProfileStringEntry( Process,
  1857. Thread,
  1858. Parameters,
  1859. IniFilePath,
  1860. SectionName,
  1861. VariableName,
  1862. VariableValue
  1863. );
  1864. }
  1865. }
  1866. return TRUE;
  1867. }
  1868. else {
  1869. return WritePrivateProfileStringExit( Process,
  1870. Thread,
  1871. Parameters
  1872. );
  1873. }
  1874. }
  1875. BOOLEAN
  1876. WritePrivateProfileStringWHandler(
  1877. PPROCESS_INFO Process,
  1878. PTHREAD_INFO Thread,
  1879. PAPI_SAVED_PARAMETERS Parameters
  1880. )
  1881. {
  1882. PWRITEPRIVATEPROFILESTRINGW_PARAMETERS p = &Parameters->InputParameters.WritePrivateProfileStringW;
  1883. PWSTR SectionName, VariableName, FileName, VariableValue;
  1884. PWSTR IniFilePath;
  1885. if (!Parameters->ReturnValueValid) {
  1886. FileName = NULL;
  1887. IniFilePath = NULL;
  1888. SectionName = NULL;
  1889. VariableName = NULL;
  1890. VariableValue = NULL;
  1891. if (CaptureUnicode( Process, p->lpFileName, FALSE, NULL, &FileName ) &&
  1892. GetIniFilePath( FileName, &IniFilePath ) &&
  1893. CaptureUnicode( Process, p->lpAppName, FALSE, &SectionName, NULL ) &&
  1894. CaptureUnicode( Process, p->lpKeyName, FALSE, &VariableName, NULL ) &&
  1895. CaptureUnicode( Process, p->lpString, FALSE, NULL, &VariableValue )
  1896. ) {
  1897. if (FileName != NULL || SectionName != NULL) {
  1898. return WritePrivateProfileStringEntry( Process,
  1899. Thread,
  1900. Parameters,
  1901. IniFilePath,
  1902. SectionName,
  1903. VariableName,
  1904. VariableValue );
  1905. }
  1906. }
  1907. return TRUE;
  1908. }
  1909. return WritePrivateProfileStringExit( Process,
  1910. Thread,
  1911. Parameters );
  1912. }
  1913. BOOLEAN
  1914. WritePrivateProfileSectionEntry(
  1915. PPROCESS_INFO Process,
  1916. PTHREAD_INFO Thread,
  1917. PAPI_SAVED_PARAMETERS Parameters,
  1918. PWSTR IniFilePath,
  1919. PWSTR SectionName,
  1920. PWSTR SectionValue
  1921. )
  1922. {
  1923. if (CreateSavedCallState( Process,
  1924. &Parameters->SavedCallState,
  1925. WriteIniSection,
  1926. HANDLE_TYPE_NONE,
  1927. IniFilePath,
  1928. SectionName,
  1929. SectionValue )
  1930. &&
  1931. CreateIniFileReference( IniFilePath,
  1932. (PINI_FILE_REFERENCE *)&Parameters->SavedCallState.Reference )
  1933. ) {
  1934. return TRUE;
  1935. }
  1936. FreeMem( &SectionValue );
  1937. return FALSE;
  1938. }
  1939. BOOLEAN
  1940. WritePrivateProfileSectionExit(
  1941. PPROCESS_INFO Process,
  1942. PTHREAD_INFO Thread,
  1943. PAPI_SAVED_PARAMETERS Parameters
  1944. )
  1945. {
  1946. PAPI_SAVED_CALL_STATE CallState;
  1947. PINI_FILE_REFERENCE IniFileReference;
  1948. PINI_SECTION_REFERENCE IniSectionReference;
  1949. PINI_VARIABLE_REFERENCE IniVariableReference;
  1950. PWSTR VariableName, VariableValue;
  1951. UNICODE_STRING UnicodeString;
  1952. if (Parameters->ReturnValue.ReturnedLong != 0) {
  1953. CallState = &Parameters->SavedCallState;
  1954. IniFileReference = FindIniFileReference( CallState->FullName );
  1955. if (IniFileReference == NULL) {
  1956. return TRUE;
  1957. }
  1958. IniSectionReference = FindIniSectionReference( IniFileReference,
  1959. CallState->SetIniSection.SectionName,
  1960. (BOOLEAN)(CallState->SetIniSection.SectionValue != NULL) );
  1961. if (IniSectionReference == NULL) {
  1962. return TRUE;
  1963. }
  1964. if (CallState->SetIniSection.SectionValue == NULL) {
  1965. IniSectionReference->Deleted = TRUE;
  1966. } else {
  1967. VariableName = CallState->SetIniSection.SectionValue;
  1968. while (*VariableName) {
  1969. VariableValue = VariableName;
  1970. while (*VariableValue != UNICODE_NULL && *VariableValue != L'=') {
  1971. VariableValue += 1;
  1972. }
  1973. if (*VariableValue != L'=') {
  1974. break;
  1975. }
  1976. *VariableValue++ = UNICODE_NULL;
  1977. RtlInitUnicodeString( &UnicodeString, VariableName );
  1978. IniVariableReference = FindIniVariableReference( IniSectionReference,
  1979. AddName( &UnicodeString ),
  1980. (BOOLEAN)(*VariableValue != UNICODE_NULL)
  1981. );
  1982. if (IniVariableReference != NULL) {
  1983. if (*VariableValue != UNICODE_NULL) {
  1984. FreeMem( &IniVariableReference->Value );
  1985. IniVariableReference->Value = AllocMem( (wcslen( VariableValue ) + 1) * sizeof( WCHAR ) );
  1986. wcscpy( IniVariableReference->Value, VariableValue );
  1987. if (!IniVariableReference->Created) {
  1988. if (!wcscmp( IniVariableReference->Value,
  1989. IniVariableReference->OriginalValue
  1990. ) )
  1991. {
  1992. FreeMem( &IniVariableReference->Value );
  1993. } else {
  1994. IniVariableReference->Modified = TRUE;
  1995. }
  1996. }
  1997. } else
  1998. if (!IniVariableReference->Created) {
  1999. IniVariableReference->Deleted = TRUE;
  2000. } else {
  2001. DestroyIniVariableReference( IniVariableReference );
  2002. }
  2003. }
  2004. VariableName = VariableValue;
  2005. while (*VariableName++ != UNICODE_NULL) {}
  2006. }
  2007. }
  2008. }
  2009. return TRUE;
  2010. }
  2011. BOOLEAN
  2012. WritePrivateProfileSectionAHandler(
  2013. PPROCESS_INFO Process,
  2014. PTHREAD_INFO Thread,
  2015. PAPI_SAVED_PARAMETERS Parameters
  2016. )
  2017. {
  2018. PWRITEPRIVATEPROFILESECTIONA_PARAMETERS p = &Parameters->InputParameters.WritePrivateProfileSectionA;
  2019. PWSTR SectionName, FileName, SectionValue;
  2020. PWSTR IniFilePath;
  2021. if (!Parameters->ReturnValueValid) {
  2022. FileName = NULL;
  2023. SectionValue = NULL;
  2024. if (CaptureAnsiAsUnicode( Process, p->lpFileName, FALSE, NULL, &FileName ) &&
  2025. GetIniFilePath( FileName, &IniFilePath ) &&
  2026. CaptureAnsiAsUnicode( Process, p->lpAppName, FALSE, &SectionName, NULL ) &&
  2027. CaptureAnsiAsUnicode( Process, p->lpString, TRUE, NULL, &SectionValue )
  2028. ) {
  2029. return WritePrivateProfileSectionEntry( Process,
  2030. Thread,
  2031. Parameters,
  2032. IniFilePath,
  2033. SectionName,
  2034. SectionValue
  2035. );
  2036. }
  2037. return FALSE;
  2038. }
  2039. else {
  2040. return WritePrivateProfileSectionExit( Process,
  2041. Thread,
  2042. Parameters
  2043. );
  2044. }
  2045. }
  2046. BOOLEAN
  2047. WritePrivateProfileSectionWHandler(
  2048. PPROCESS_INFO Process,
  2049. PTHREAD_INFO Thread,
  2050. PAPI_SAVED_PARAMETERS Parameters
  2051. )
  2052. {
  2053. PWRITEPRIVATEPROFILESECTIONW_PARAMETERS p = &Parameters->InputParameters.WritePrivateProfileSectionW;
  2054. PWSTR SectionName, FileName, SectionValue;
  2055. PWSTR IniFilePath;
  2056. if (!Parameters->ReturnValueValid) {
  2057. FileName = NULL;
  2058. SectionValue = NULL;
  2059. if (CaptureUnicode( Process, p->lpFileName, FALSE, NULL, &FileName ) &&
  2060. GetIniFilePath( FileName, &IniFilePath ) &&
  2061. CaptureUnicode( Process, p->lpAppName, FALSE, &SectionName, NULL ) &&
  2062. CaptureUnicode( Process, p->lpString, TRUE, NULL, &SectionValue )
  2063. ) {
  2064. return WritePrivateProfileSectionEntry( Process,
  2065. Thread,
  2066. Parameters,
  2067. IniFilePath,
  2068. SectionName,
  2069. SectionValue
  2070. );
  2071. }
  2072. return FALSE;
  2073. }
  2074. else {
  2075. return WritePrivateProfileSectionExit( Process,
  2076. Thread,
  2077. Parameters
  2078. );
  2079. }
  2080. }
  2081. BOOLEAN
  2082. RegConnectRegistryWHandler(
  2083. PPROCESS_INFO Process,
  2084. PTHREAD_INFO Thread,
  2085. PAPI_SAVED_PARAMETERS Parameters
  2086. )
  2087. {
  2088. PREGCONNECTREGISTRYW_PARAMETERS p = &Parameters->InputParameters.RegConnectRegistryW;
  2089. PWSTR MachineName;
  2090. LONG ErrorCode;
  2091. HKEY hKey;
  2092. if (!Parameters->ReturnValueValid) {
  2093. MachineName = NULL;
  2094. if (!CaptureUnicode( Process, p->lpMachineName, FALSE, NULL, &MachineName )) {
  2095. MachineName = L"Unknown";
  2096. }
  2097. if (AskUser( MB_OKCANCEL,
  2098. INSTALER_ASKUSER_REGCONNECT,
  2099. 1,
  2100. MachineName
  2101. ) == IDCANCEL
  2102. ) {
  2103. FreeMem( &MachineName );
  2104. Parameters->AbortCall = TRUE;
  2105. return TRUE;
  2106. }
  2107. else {
  2108. FreeMem( &MachineName );
  2109. return FALSE;
  2110. }
  2111. }
  2112. else
  2113. if (Parameters->ReturnValue.ReturnedLong == 0) {
  2114. ErrorCode = ERROR_ACCESS_DENIED;
  2115. if (SetProcedureReturnValue( Process,
  2116. Thread,
  2117. &ErrorCode,
  2118. sizeof( ErrorCode )
  2119. )
  2120. ) {
  2121. if (ReadMemory( Process,
  2122. p->phkResult,
  2123. &hKey,
  2124. sizeof( hKey ),
  2125. "phkResult"
  2126. )
  2127. ) {
  2128. RegCloseKey( hKey );
  2129. hKey = NULL;
  2130. WriteMemory( Process,
  2131. p->phkResult,
  2132. &hKey,
  2133. sizeof( hKey ),
  2134. "phkResult"
  2135. );
  2136. }
  2137. }
  2138. }
  2139. return TRUE;
  2140. }
  2141. BOOLEAN
  2142. ExitWindowsExHandler(
  2143. PPROCESS_INFO Process,
  2144. PTHREAD_INFO Thread,
  2145. PAPI_SAVED_PARAMETERS Parameters
  2146. )
  2147. {
  2148. PEXITWINDOWSEX_PARAMETERS p = &Parameters->InputParameters.ExitWindowsEx;
  2149. PWSTR MachineName;
  2150. LONG ErrorCode;
  2151. HKEY hKey;
  2152. if (!Parameters->ReturnValueValid) {
  2153. //
  2154. // About to shutdown, save .IML file
  2155. //
  2156. return TRUE;
  2157. }
  2158. else
  2159. if (!Parameters->ReturnValue.ReturnedBool) {
  2160. //
  2161. // Shutdown attempt failed, keep going
  2162. //
  2163. }
  2164. return TRUE;
  2165. }