ReactOS 0.4.15-dev-7924-g5949c20
fileqsup.c File Reference
#include "usetup.h"
#include <debug.h>
Include dependency graph for fileqsup.c:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _QUEUEENTRY
 
struct  _FILEQUEUEHEADER
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _QUEUEENTRY QUEUEENTRY
 
typedef struct _QUEUEENTRYPQUEUEENTRY
 
typedef struct _FILEQUEUEHEADER FILEQUEUEHEADER
 
typedef struct _FILEQUEUEHEADERPFILEQUEUEHEADER
 

Functions

static NTSTATUS SetupExtractFile (IN OUT PFILEQUEUEHEADER QueueHeader, IN PCWSTR CabinetFileName, IN PCWSTR SourceFileName, IN PCWSTR DestinationPathName)
 
HSPFILEQ WINAPI SetupOpenFileQueue (VOID)
 
static VOID SetupDeleteQueueEntry (IN PQUEUEENTRY Entry)
 
BOOL WINAPI SetupCloseFileQueue (IN HSPFILEQ QueueHandle)
 
BOOL WINAPI SetupQueueCopyWithCab (IN HSPFILEQ QueueHandle, IN PCWSTR SourceRootPath, IN PCWSTR SourcePath OPTIONAL, IN PCWSTR SourceFileName, IN PCWSTR SourceDescription OPTIONAL, IN PCWSTR SourceCabinet OPTIONAL, IN PCWSTR SourceTagFile OPTIONAL, IN PCWSTR TargetDirectory, IN PCWSTR TargetFileName OPTIONAL, IN ULONG CopyStyle)
 
BOOL WINAPI SetupQueueDeleteW (IN HSPFILEQ QueueHandle, IN PCWSTR PathPart1, IN PCWSTR PathPart2 OPTIONAL)
 
BOOL WINAPI SetupQueueRenameW (IN HSPFILEQ QueueHandle, IN PCWSTR SourcePath, IN PCWSTR SourceFileName OPTIONAL, IN PCWSTR TargetPath OPTIONAL, IN PCWSTR TargetFileName)
 
BOOL WINAPI SetupCommitFileQueueW (IN HWND Owner, IN HSPFILEQ QueueHandle, IN PSP_FILE_CALLBACK_W MsgHandler, IN PVOID Context OPTIONAL)
 

Variables

pSpFileQueueOpen SpFileQueueOpen = SetupOpenFileQueue
 
pSpFileQueueClose SpFileQueueClose = SetupCloseFileQueue
 
pSpFileQueueCopy SpFileQueueCopy = SetupQueueCopyWithCab
 
pSpFileQueueDelete SpFileQueueDelete = SetupQueueDeleteW
 
pSpFileQueueRename SpFileQueueRename = SetupQueueRenameW
 
pSpFileQueueCommit SpFileQueueCommit = SetupCommitFileQueueW
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 34 of file fileqsup.c.

Typedef Documentation

◆ FILEQUEUEHEADER

◆ PFILEQUEUEHEADER

◆ PQUEUEENTRY

◆ QUEUEENTRY

Function Documentation

◆ SetupCloseFileQueue()

BOOL WINAPI SetupCloseFileQueue ( IN HSPFILEQ  QueueHandle)

Definition at line 219 of file fileqsup.c.

221{
222 PFILEQUEUEHEADER QueueHeader;
223 PLIST_ENTRY ListEntry;
225
226 if (QueueHandle == NULL)
227 return FALSE;
228
229 QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
230
231 /* Delete the delete queue */
232 while (!IsListEmpty(&QueueHeader->DeleteQueue))
233 {
234 ListEntry = RemoveHeadList(&QueueHeader->DeleteQueue);
235 Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
237 }
238
239 /* Delete the rename queue */
240 while (!IsListEmpty(&QueueHeader->RenameQueue))
241 {
242 ListEntry = RemoveHeadList(&QueueHeader->RenameQueue);
243 Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
245 }
246
247 /* Delete the copy queue */
248 while (!IsListEmpty(&QueueHeader->CopyQueue))
249 {
250 ListEntry = RemoveHeadList(&QueueHeader->CopyQueue);
251 Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
253 }
254
255 /* Delete queue header */
256 RtlFreeHeap(ProcessHeap, 0, QueueHeader);
257
258 return TRUE;
259}
HANDLE ProcessHeap
Definition: servman.c:15
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
base of all file and directory entries
Definition: entries.h:83
LIST_ENTRY DeleteQueue
Definition: fileqsup.c:52
LIST_ENTRY RenameQueue
Definition: fileqsup.c:55
LIST_ENTRY CopyQueue
Definition: fileqsup.c:58
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
struct _FILEQUEUEHEADER * PFILEQUEUEHEADER
static VOID SetupDeleteQueueEntry(IN PQUEUEENTRY Entry)
Definition: fileqsup.c:188

◆ SetupCommitFileQueueW()

BOOL WINAPI SetupCommitFileQueueW ( IN HWND  Owner,
IN HSPFILEQ  QueueHandle,
IN PSP_FILE_CALLBACK_W  MsgHandler,
IN PVOID Context  OPTIONAL 
)

Definition at line 619 of file fileqsup.c.

624{
625 BOOL Success = TRUE; // Suppose success
626 UINT Result;
628 PFILEQUEUEHEADER QueueHeader;
629 PLIST_ENTRY ListEntry;
631 FILEPATHS_W FilePathInfo;
632 WCHAR FileSrcPath[MAX_PATH];
633 WCHAR FileDstPath[MAX_PATH];
634
635 if (QueueHandle == NULL)
636 return FALSE;
637
638 QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
639
640 Result = MsgHandler(Context,
643 0);
644 if (Result == FILEOP_ABORT)
645 return FALSE;
646
647
648 /*
649 * Commit the delete queue
650 */
651
652 if (!IsListEmpty(&QueueHeader->DeleteQueue))
653 {
654 Result = MsgHandler(Context,
657 QueueHeader->DeleteCount);
658 if (Result == FILEOP_ABORT)
659 {
660 Success = FALSE;
661 goto Quit;
662 }
663 }
664
665 for (ListEntry = QueueHeader->DeleteQueue.Flink;
666 ListEntry != &QueueHeader->DeleteQueue;
667 ListEntry = ListEntry->Flink)
668 {
669 Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
670
671 /* Build the full target path */
672 CombinePaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
673 Entry->TargetDirectory, Entry->TargetFileName);
674
675 DPRINT1(" -----> " "Delete: '%S'\n", FileDstPath);
676
677 FilePathInfo.Target = FileDstPath;
678 FilePathInfo.Source = NULL;
679 FilePathInfo.Win32Error = STATUS_SUCCESS;
680 FilePathInfo.Flags = 0; // FIXME: Unused yet...
681
682 Result = MsgHandler(Context,
684 (UINT_PTR)&FilePathInfo,
686 if (Result == FILEOP_ABORT)
687 {
688 Success = FALSE;
689 goto EndDelete;
690 }
691 else if (Result == FILEOP_SKIP)
692 goto EndDelete;
693 // else (Result == FILEOP_DOIT)
694
695RetryDelete:
696 /* Force-delete the file */
697 Status = SetupDeleteFile(FileDstPath, TRUE);
698 if (!NT_SUCCESS(Status))
699 {
700 /* An error happened */
701 FilePathInfo.Win32Error = (UINT)Status;
702 Result = MsgHandler(Context,
704 (UINT_PTR)&FilePathInfo,
705 0);
706 if (Result == FILEOP_ABORT)
707 {
708 Success = FALSE;
709 goto EndDelete;
710 }
711 else if (Result == FILEOP_SKIP)
712 goto EndDelete;
713 else if (Result == FILEOP_RETRY)
714 goto RetryDelete;
715
716 Success = FALSE;
717 }
718
719EndDelete:
720 /* This notification is always sent, even in case of error */
721 FilePathInfo.Win32Error = (UINT)Status;
722 MsgHandler(Context,
724 (UINT_PTR)&FilePathInfo,
725 0);
726 if (Success == FALSE /* && Result == FILEOP_ABORT */)
727 goto Quit;
728 }
729
730 if (!IsListEmpty(&QueueHeader->DeleteQueue))
731 {
732 MsgHandler(Context,
735 0);
736 }
737
738
739 /*
740 * Commit the rename queue
741 */
742
743 if (!IsListEmpty(&QueueHeader->RenameQueue))
744 {
745 Result = MsgHandler(Context,
748 QueueHeader->RenameCount);
749 if (Result == FILEOP_ABORT)
750 {
751 Success = FALSE;
752 goto Quit;
753 }
754 }
755
756 for (ListEntry = QueueHeader->RenameQueue.Flink;
757 ListEntry != &QueueHeader->RenameQueue;
758 ListEntry = ListEntry->Flink)
759 {
760 Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
761
762 /* Build the full source path */
763 CombinePaths(FileSrcPath, ARRAYSIZE(FileSrcPath), 2,
764 Entry->SourcePath, Entry->SourceFileName);
765
766 /* Build the full target path */
767 CombinePaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
768 Entry->TargetDirectory, Entry->TargetFileName);
769
770 DPRINT1(" -----> " "Rename: '%S' ==> '%S'\n", FileSrcPath, FileDstPath);
771
772 FilePathInfo.Target = FileDstPath;
773 FilePathInfo.Source = FileSrcPath;
774 FilePathInfo.Win32Error = STATUS_SUCCESS;
775 FilePathInfo.Flags = 0; // FIXME: Unused yet...
776
777 Result = MsgHandler(Context,
779 (UINT_PTR)&FilePathInfo,
781 if (Result == FILEOP_ABORT)
782 {
783 Success = FALSE;
784 goto EndRename;
785 }
786 else if (Result == FILEOP_SKIP)
787 goto EndRename;
788 // else (Result == FILEOP_DOIT)
789
790RetryRename:
791 /* Move or rename the file */
792 Status = SetupMoveFile(FileSrcPath, FileDstPath,
796 if (!NT_SUCCESS(Status))
797 {
798 /* An error happened */
799 FilePathInfo.Win32Error = (UINT)Status;
800 Result = MsgHandler(Context,
802 (UINT_PTR)&FilePathInfo,
803 0);
804 if (Result == FILEOP_ABORT)
805 {
806 Success = FALSE;
807 goto EndRename;
808 }
809 else if (Result == FILEOP_SKIP)
810 goto EndRename;
811 else if (Result == FILEOP_RETRY)
812 goto RetryRename;
813
814 Success = FALSE;
815 }
816
817EndRename:
818 /* This notification is always sent, even in case of error */
819 FilePathInfo.Win32Error = (UINT)Status;
820 MsgHandler(Context,
822 (UINT_PTR)&FilePathInfo,
823 0);
824 if (Success == FALSE /* && Result == FILEOP_ABORT */)
825 goto Quit;
826 }
827
828 if (!IsListEmpty(&QueueHeader->RenameQueue))
829 {
830 MsgHandler(Context,
833 0);
834 }
835
836
837 /*
838 * Commit the copy queue
839 */
840
841 if (!IsListEmpty(&QueueHeader->CopyQueue))
842 {
843 Result = MsgHandler(Context,
846 QueueHeader->CopyCount);
847 if (Result == FILEOP_ABORT)
848 {
849 Success = FALSE;
850 goto Quit;
851 }
852 }
853
854 for (ListEntry = QueueHeader->CopyQueue.Flink;
855 ListEntry != &QueueHeader->CopyQueue;
856 ListEntry = ListEntry->Flink)
857 {
858 Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
859
860 //
861 // TODO: Send a SPFILENOTIFY_NEEDMEDIA notification
862 // when we switch to a new installation media.
863 // Param1 = (UINT_PTR)(PSOURCE_MEDIA)SourceMediaInfo;
864 // Param2 = (UINT_PTR)(TCHAR[MAX_PATH])NewPathInfo;
865 //
866
867 /* Build the full source path */
868 if (Entry->SourceCabinet == NULL)
869 {
870 CombinePaths(FileSrcPath, ARRAYSIZE(FileSrcPath), 3,
871 Entry->SourceRootPath, Entry->SourcePath,
872 Entry->SourceFileName);
873 }
874 else
875 {
876 /*
877 * The cabinet must be in Entry->SourceRootPath only!
878 * (Should we ignore Entry->SourcePath?)
879 */
880 CombinePaths(FileSrcPath, ARRAYSIZE(FileSrcPath), 3,
881 Entry->SourceRootPath, Entry->SourcePath,
882 Entry->SourceCabinet);
883 }
884
885 /* Build the full target path */
886 RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath), Entry->TargetDirectory);
887 if (Entry->SourceCabinet == NULL)
888 {
889 /* If the file is not in a cabinet, possibly use a different target name */
890 if (Entry->TargetFileName != NULL)
891 ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, Entry->TargetFileName);
892 else
893 ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, Entry->SourceFileName);
894 }
895 else
896 {
897 ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, Entry->SourceFileName);
898 }
899
900 DPRINT(" -----> " "Copy: '%S' ==> '%S'\n", FileSrcPath, FileDstPath);
901
902 //
903 // Technically, here we should create the target directory,
904 // if it does not already exist... before calling the handler!
905 //
906
907 FilePathInfo.Target = FileDstPath;
908 FilePathInfo.Source = FileSrcPath;
909 FilePathInfo.Win32Error = STATUS_SUCCESS;
910 FilePathInfo.Flags = 0; // FIXME: Unused yet...
911
912 Result = MsgHandler(Context,
914 (UINT_PTR)&FilePathInfo,
916 if (Result == FILEOP_ABORT)
917 {
918 Success = FALSE;
919 goto EndCopy;
920 }
921 else if (Result == FILEOP_SKIP)
922 goto EndCopy;
923 // else (Result == FILEOP_DOIT)
924
925RetryCopy:
926 if (Entry->SourceCabinet != NULL)
927 {
928 /*
929 * The file is in a cabinet, use only the destination path
930 * and keep the source name as the target name.
931 */
932 /* Extract the file from the cabinet */
933 Status = SetupExtractFile(QueueHeader,
934 FileSrcPath, // Specifies the cabinet path
935 Entry->SourceFileName,
936 Entry->TargetDirectory);
937 }
938 else
939 {
940 /* Copy the file */
941 Status = SetupCopyFile(FileSrcPath, FileDstPath, FALSE);
942 }
943
944 if (!NT_SUCCESS(Status))
945 {
946 /* An error happened */
947 FilePathInfo.Win32Error = (UINT)Status;
948 Result = MsgHandler(Context,
950 (UINT_PTR)&FilePathInfo,
951 (UINT_PTR)NULL); // FIXME: Unused yet...
952 if (Result == FILEOP_ABORT)
953 {
954 Success = FALSE;
955 goto EndCopy;
956 }
957 else if (Result == FILEOP_SKIP)
958 goto EndCopy;
959 else if (Result == FILEOP_RETRY)
960 goto RetryCopy;
961 else if (Result == FILEOP_NEWPATH)
962 goto RetryCopy; // TODO!
963
964 Success = FALSE;
965 }
966
967EndCopy:
968 /* This notification is always sent, even in case of error */
969 FilePathInfo.Win32Error = (UINT)Status;
970 MsgHandler(Context,
972 (UINT_PTR)&FilePathInfo,
973 0);
974 if (Success == FALSE /* && Result == FILEOP_ABORT */)
975 goto Quit;
976 }
977
978 if (!IsListEmpty(&QueueHeader->CopyQueue))
979 {
980 MsgHandler(Context,
983 0);
984 }
985
986
987Quit:
988 /* All the queues have been committed */
989 MsgHandler(Context,
992 0);
993
994 return Success;
995}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
@ Success
Definition: eventcreate.c:712
#define SPFILENOTIFY_ENDDELETE
Definition: fileqsup.h:28
#define FILEOP_COPY
Definition: fileqsup.h:42
#define SPFILENOTIFY_RENAMEERROR
Definition: fileqsup.h:33
#define FILEOP_SKIP
Definition: fileqsup.h:49
#define SPFILENOTIFY_STARTDELETE
Definition: fileqsup.h:27
#define SPFILENOTIFY_STARTSUBQUEUE
Definition: fileqsup.h:24
#define FILEOP_RETRY
Definition: fileqsup.h:50
#define FILEOP_NEWPATH
Definition: fileqsup.h:51
#define SPFILENOTIFY_ENDQUEUE
Definition: fileqsup.h:23
#define SPFILENOTIFY_ENDCOPY
Definition: fileqsup.h:36
#define SPFILENOTIFY_DELETEERROR
Definition: fileqsup.h:29
#define SPFILENOTIFY_STARTCOPY
Definition: fileqsup.h:35
#define SPFILENOTIFY_COPYERROR
Definition: fileqsup.h:37
#define FILEOP_RENAME
Definition: fileqsup.h:43
#define SPFILENOTIFY_ENDSUBQUEUE
Definition: fileqsup.h:25
#define SPFILENOTIFY_STARTRENAME
Definition: fileqsup.h:31
#define SPFILENOTIFY_ENDRENAME
Definition: fileqsup.h:32
#define FILEOP_DELETE
Definition: fileqsup.h:44
#define FILEOP_ABORT
Definition: fileqsup.h:47
#define SPFILENOTIFY_STARTQUEUE
Definition: fileqsup.h:22
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:681
NTSTATUS SetupMoveFile(IN PCWSTR ExistingFileName, IN PCWSTR NewFileName, IN ULONG Flags)
Definition: filesup.c:480
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:659
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:240
NTSTATUS SetupDeleteFile(IN PCWSTR FileName, IN BOOLEAN ForceDelete)
Definition: filesup.c:151
#define MOVEFILE_WRITE_THROUGH
Definition: filesup.h:30
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
unsigned int BOOL
Definition: ntddk_ex.h:94
Status
Definition: gdiplustypes.h:25
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1597
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
ULONG Flags
Definition: fileqsup.h:63
UINT Win32Error
Definition: fileqsup.h:62
PCWSTR Source
Definition: fileqsup.h:61
PCWSTR Target
Definition: fileqsup.h:60
ULONG RenameCount
Definition: fileqsup.c:56
ULONG DeleteCount
Definition: fileqsup.c:53
ULONG CopyCount
Definition: fileqsup.c:59
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static NTSTATUS SetupExtractFile(IN OUT PFILEQUEUEHEADER QueueHeader, IN PCWSTR CabinetFileName, IN PCWSTR SourceFileName, IN PCWSTR DestinationPathName)
Definition: fileqsup.c:71
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ SetupDeleteQueueEntry()

static VOID SetupDeleteQueueEntry ( IN PQUEUEENTRY  Entry)
static

Definition at line 188 of file fileqsup.c.

190{
191 if (Entry == NULL)
192 return;
193
194 /* Delete all strings */
195 if (Entry->SourceCabinet != NULL)
196 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
197
198 if (Entry->SourceRootPath != NULL)
199 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
200
201 if (Entry->SourcePath != NULL)
202 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
203
204 if (Entry->SourceFileName != NULL)
205 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
206
207 if (Entry->TargetDirectory != NULL)
208 RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
209
210 if (Entry->TargetFileName != NULL)
211 RtlFreeHeap(ProcessHeap, 0, Entry->TargetFileName);
212
213 /* Delete queue entry */
215}

Referenced by SetupCloseFileQueue().

◆ SetupExtractFile()

static NTSTATUS SetupExtractFile ( IN OUT PFILEQUEUEHEADER  QueueHeader,
IN PCWSTR  CabinetFileName,
IN PCWSTR  SourceFileName,
IN PCWSTR  DestinationPathName 
)
static

Definition at line 71 of file fileqsup.c.

76{
77 ULONG CabStatus;
78
79 DPRINT("SetupExtractFile(CabinetFileName: '%S', SourceFileName: '%S', DestinationPathName: '%S')\n",
80 CabinetFileName, SourceFileName, DestinationPathName);
81
82 if (QueueHeader->HasCurrentCabinet)
83 {
84 DPRINT("CurrentCabinetName: '%S'\n", QueueHeader->CurrentCabinetName);
85 }
86
87 if (QueueHeader->HasCurrentCabinet &&
88 (wcscmp(CabinetFileName, QueueHeader->CurrentCabinetName) == 0))
89 {
90 DPRINT("Using same cabinet as last time\n");
91
92 /* Use our last location because the files should be sequential */
93 CabStatus = CabinetFindNextFileSequential(&QueueHeader->CabinetContext,
94 SourceFileName,
95 &QueueHeader->Search);
96 if (CabStatus != CAB_STATUS_SUCCESS)
97 {
98 DPRINT("Sequential miss on file: %S\n", SourceFileName);
99
100 /* Looks like we got unlucky */
101 CabStatus = CabinetFindFirst(&QueueHeader->CabinetContext,
102 SourceFileName,
103 &QueueHeader->Search);
104 }
105 }
106 else
107 {
108 DPRINT("Using new cabinet\n");
109
110 if (QueueHeader->HasCurrentCabinet)
111 {
112 QueueHeader->HasCurrentCabinet = FALSE;
113 CabinetCleanup(&QueueHeader->CabinetContext);
114 }
115
116 RtlStringCchCopyW(QueueHeader->CurrentCabinetName,
117 ARRAYSIZE(QueueHeader->CurrentCabinetName),
118 CabinetFileName);
119
120 CabinetInitialize(&QueueHeader->CabinetContext);
121 CabinetSetEventHandlers(&QueueHeader->CabinetContext,
122 NULL, NULL, NULL, NULL);
123 CabinetSetCabinetName(&QueueHeader->CabinetContext, CabinetFileName);
124
125 CabStatus = CabinetOpen(&QueueHeader->CabinetContext);
126 if (CabStatus == CAB_STATUS_SUCCESS)
127 {
128 DPRINT("Opened cabinet %S\n", CabinetFileName /*CabinetGetCabinetName(&QueueHeader->CabinetContext)*/);
129 QueueHeader->HasCurrentCabinet = TRUE;
130 }
131 else
132 {
133 DPRINT("Cannot open cabinet (%d)\n", CabStatus);
134 return STATUS_UNSUCCESSFUL;
135 }
136
137 /* We have to start at the beginning here */
138 CabStatus = CabinetFindFirst(&QueueHeader->CabinetContext,
139 SourceFileName,
140 &QueueHeader->Search);
141 }
142
143 if (CabStatus != CAB_STATUS_SUCCESS)
144 {
145 DPRINT1("Unable to find '%S' in cabinet '%S'\n",
146 SourceFileName, CabinetGetCabinetName(&QueueHeader->CabinetContext));
147 return STATUS_UNSUCCESSFUL;
148 }
149
150 CabinetSetDestinationPath(&QueueHeader->CabinetContext, DestinationPathName);
151 CabStatus = CabinetExtractFile(&QueueHeader->CabinetContext, &QueueHeader->Search);
152 if (CabStatus != CAB_STATUS_SUCCESS)
153 {
154 DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus);
155 return STATUS_UNSUCCESSFUL;
156 }
157
158 return STATUS_SUCCESS;
159}
#define CAB_STATUS_SUCCESS
Definition: cabinet.h:23
ULONG CabinetOpen(IN OUT PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:627
ULONG CabinetFindFirst(IN PCABINET_CONTEXT CabinetContext, IN PCWSTR FileName, IN OUT PCAB_SEARCH Search)
Definition: cabinet.c:826
PCWSTR CabinetGetCabinetName(IN PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:574
ULONG CabinetExtractFile(IN PCABINET_CONTEXT CabinetContext, IN PCAB_SEARCH Search)
Definition: cabinet.c:965
VOID CabinetSetEventHandlers(IN PCABINET_CONTEXT CabinetContext, IN PCABINET_OVERWRITE Overwrite, IN PCABINET_EXTRACT Extract, IN PCABINET_DISK_CHANGE DiskChange, IN PCABINET_CREATE_FILE CreateFile)
Definition: cabinet.c:1346
VOID CabinetInitialize(IN OUT PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:507
VOID CabinetCleanup(IN OUT PCABINET_CONTEXT CabinetContext)
Definition: cabinet.c:535
VOID CabinetSetCabinetName(IN PCABINET_CONTEXT CabinetContext, IN PCWSTR FileName)
Definition: cabinet.c:586
VOID CabinetSetDestinationPath(IN PCABINET_CONTEXT CabinetContext, IN PCWSTR DestinationPath)
Definition: cabinet.c:599
ULONG CabinetFindNextFileSequential(IN PCABINET_CONTEXT CabinetContext, IN PCWSTR FileName, IN OUT PCAB_SEARCH Search)
Definition: cabinet.c:939
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by SetupCommitFileQueueW().

◆ SetupOpenFileQueue()

HSPFILEQ WINAPI SetupOpenFileQueue ( VOID  )

Definition at line 163 of file fileqsup.c.

164{
165 PFILEQUEUEHEADER QueueHeader;
166
167 /* Allocate the queue header */
168 QueueHeader = RtlAllocateHeap(ProcessHeap, 0, sizeof(FILEQUEUEHEADER));
169 if (QueueHeader == NULL)
170 return NULL;
171
172 RtlZeroMemory(QueueHeader, sizeof(FILEQUEUEHEADER));
173
174 /* Initialize the file queues */
175 InitializeListHead(&QueueHeader->DeleteQueue);
176 QueueHeader->DeleteCount = 0;
177 InitializeListHead(&QueueHeader->RenameQueue);
178 QueueHeader->RenameCount = 0;
179 InitializeListHead(&QueueHeader->CopyQueue);
180 QueueHeader->CopyCount = 0;
181
182 QueueHeader->HasCurrentCabinet = FALSE;
183
184 return (HSPFILEQ)QueueHeader;
185}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BOOLEAN HasCurrentCabinet
Definition: fileqsup.c:61
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ SetupQueueCopyWithCab()

BOOL WINAPI SetupQueueCopyWithCab ( IN HSPFILEQ  QueueHandle,
IN PCWSTR  SourceRootPath,
IN PCWSTR SourcePath  OPTIONAL,
IN PCWSTR  SourceFileName,
IN PCWSTR SourceDescription  OPTIONAL,
IN PCWSTR SourceCabinet  OPTIONAL,
IN PCWSTR SourceTagFile  OPTIONAL,
IN PCWSTR  TargetDirectory,
IN PCWSTR TargetFileName  OPTIONAL,
IN ULONG  CopyStyle 
)

Definition at line 264 of file fileqsup.c.

275{
276 PFILEQUEUEHEADER QueueHeader;
279
280 if (QueueHandle == NULL ||
281 SourceRootPath == NULL ||
282 SourceFileName == NULL ||
283 TargetDirectory == NULL)
284 {
285 return FALSE;
286 }
287
288 QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
289
290 DPRINT("SetupQueueCopy(Cab '%S', SrcRootPath '%S', SrcPath '%S', SrcFN '%S' --> DstPath '%S', DstFN '%S')\n",
291 SourceCabinet ? SourceCabinet : L"n/a",
292 SourceRootPath, SourcePath, SourceFileName,
293 TargetDirectory, TargetFileName);
294
295 /* Allocate new queue entry */
297 if (Entry == NULL)
298 return FALSE;
299
301
302 /* Copy source cabinet if available */
303 Entry->SourceCabinet = NULL;
304 if (SourceCabinet != NULL)
305 {
306 Length = wcslen(SourceCabinet);
307 Entry->SourceCabinet = RtlAllocateHeap(ProcessHeap,
308 0,
309 (Length + 1) * sizeof(WCHAR));
310 if (Entry->SourceCabinet == NULL)
311 {
313 return FALSE;
314 }
315 RtlStringCchCopyW(Entry->SourceCabinet, Length + 1, SourceCabinet);
316 }
317
318 /* Copy source root path */
319 Length = wcslen(SourceRootPath);
320 Entry->SourceRootPath = RtlAllocateHeap(ProcessHeap,
321 0,
322 (Length + 1) * sizeof(WCHAR));
323 if (Entry->SourceRootPath == NULL)
324 {
325 if (Entry->SourceCabinet != NULL)
326 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
327
329 return FALSE;
330 }
331 RtlStringCchCopyW(Entry->SourceRootPath, Length + 1, SourceRootPath);
332
333 /* Copy source path */
334 Entry->SourcePath = NULL;
335 if (SourcePath != NULL)
336 {
337 Length = wcslen(SourcePath);
338 if ((Length > 0) && (SourcePath[Length - 1] == L'\\'))
339 Length--;
340 Entry->SourcePath = RtlAllocateHeap(ProcessHeap,
341 0,
342 (Length + 1) * sizeof(WCHAR));
343 if (Entry->SourcePath == NULL)
344 {
345 if (Entry->SourceCabinet != NULL)
346 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
347
348 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
350 return FALSE;
351 }
352 RtlStringCchCopyW(Entry->SourcePath, Length + 1, SourcePath);
353 }
354
355 /* Copy source file name */
356 Length = wcslen(SourceFileName);
357 Entry->SourceFileName = (WCHAR*)RtlAllocateHeap(ProcessHeap,
358 0,
359 (Length + 1) * sizeof(WCHAR));
360 if (Entry->SourceFileName == NULL)
361 {
362 if (Entry->SourcePath != NULL)
363 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
364
365 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
366
367 if (Entry->SourceCabinet != NULL)
368 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
369
371 return FALSE;
372 }
373 RtlStringCchCopyW(Entry->SourceFileName, Length + 1, SourceFileName);
374
375 /* Copy target directory */
376 Length = wcslen(TargetDirectory);
377 if ((Length > 0) && (TargetDirectory[Length - 1] == L'\\'))
378 Length--;
379 Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap,
380 0,
381 (Length + 1) * sizeof(WCHAR));
382 if (Entry->TargetDirectory == NULL)
383 {
384 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
385
386 if (Entry->SourcePath != NULL)
387 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
388
389 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
390
391 if (Entry->SourceCabinet != NULL)
392 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
393
395 return FALSE;
396 }
397 RtlStringCchCopyW(Entry->TargetDirectory, Length + 1, TargetDirectory);
398
399 /* Copy optional target filename */
400 Entry->TargetFileName = NULL;
401 if (TargetFileName != NULL)
402 {
403 Length = wcslen(TargetFileName);
404 Entry->TargetFileName = RtlAllocateHeap(ProcessHeap,
405 0,
406 (Length + 1) * sizeof(WCHAR));
407 if (Entry->TargetFileName == NULL)
408 {
409 RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
410 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
411
412 if (Entry->SourcePath != NULL)
413 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
414
415 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
416
417 if (Entry->SourceCabinet != NULL)
418 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
419
421 return FALSE;
422 }
423 RtlStringCchCopyW(Entry->TargetFileName, Length + 1, TargetFileName);
424 }
425
426 /* Append queue entry */
427 InsertTailList(&QueueHeader->CopyQueue, &Entry->ListEntry);
428 ++QueueHeader->CopyCount;
429
430 return TRUE;
431}
#define InsertTailList(ListHead, Entry)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50

◆ SetupQueueDeleteW()

BOOL WINAPI SetupQueueDeleteW ( IN HSPFILEQ  QueueHandle,
IN PCWSTR  PathPart1,
IN PCWSTR PathPart2  OPTIONAL 
)

Definition at line 435 of file fileqsup.c.

439{
440 PFILEQUEUEHEADER QueueHeader;
443
444 if (QueueHandle == NULL || PathPart1 == NULL)
445 {
446 return FALSE;
447 }
448
449 QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
450
451 DPRINT1("SetupQueueDeleteW(PathPart1 '%S', PathPart2 '%S')\n",
452 PathPart1, PathPart2);
453
454 /* Allocate new queue entry */
456 if (Entry == NULL)
457 return FALSE;
458
460
461 Entry->SourceCabinet = NULL;
462 Entry->SourceRootPath = NULL;
463 Entry->SourcePath = NULL;
464 Entry->SourceFileName = NULL;
465
466 /* Copy first part of path */
467 Length = wcslen(PathPart1);
468 // if ((Length > 0) && (SourcePath[Length - 1] == L'\\'))
469 // Length--;
470 Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap,
471 0,
472 (Length + 1) * sizeof(WCHAR));
473 if (Entry->TargetDirectory == NULL)
474 {
476 return FALSE;
477 }
478 RtlStringCchCopyW(Entry->TargetDirectory, Length + 1, PathPart1);
479
480 /* Copy optional second part of path */
481 if (PathPart2 != NULL)
482 {
483 Length = wcslen(PathPart2);
484 Entry->TargetFileName = RtlAllocateHeap(ProcessHeap,
485 0,
486 (Length + 1) * sizeof(WCHAR));
487 if (Entry->TargetFileName == NULL)
488 {
489 RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
491 return FALSE;
492 }
493 RtlStringCchCopyW(Entry->TargetFileName, Length + 1, PathPart2);
494 }
495
496 /* Append the queue entry */
497 InsertTailList(&QueueHeader->DeleteQueue, &Entry->ListEntry);
498 ++QueueHeader->DeleteCount;
499
500 return TRUE;
501}

◆ SetupQueueRenameW()

BOOL WINAPI SetupQueueRenameW ( IN HSPFILEQ  QueueHandle,
IN PCWSTR  SourcePath,
IN PCWSTR SourceFileName  OPTIONAL,
IN PCWSTR TargetPath  OPTIONAL,
IN PCWSTR  TargetFileName 
)

Definition at line 505 of file fileqsup.c.

511{
512 PFILEQUEUEHEADER QueueHeader;
515
516 if (QueueHandle == NULL ||
517 SourcePath == NULL ||
518 TargetFileName == NULL)
519 {
520 return FALSE;
521 }
522
523 QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
524
525 DPRINT1("SetupQueueRenameW(SrcPath '%S', SrcFN '%S' --> DstPath '%S', DstFN '%S')\n",
526 SourcePath, SourceFileName, TargetPath, TargetFileName);
527
528 /* Allocate a new queue entry */
530 if (Entry == NULL)
531 return FALSE;
532
534
535 Entry->SourceCabinet = NULL;
536 Entry->SourceRootPath = NULL;
537
538 /* Copy source path */
539 Length = wcslen(SourcePath);
540 if ((Length > 0) && (SourcePath[Length - 1] == L'\\'))
541 Length--;
542 Entry->SourcePath = RtlAllocateHeap(ProcessHeap,
543 0,
544 (Length + 1) * sizeof(WCHAR));
545 if (Entry->SourcePath == NULL)
546 {
548 return FALSE;
549 }
550 RtlStringCchCopyW(Entry->SourcePath, Length + 1, SourcePath);
551
552 /* Copy optional source file name */
553 Entry->SourceFileName = NULL;
554 if (SourceFileName != NULL)
555 {
556 Length = wcslen(SourceFileName);
557 Entry->SourceFileName = (WCHAR*)RtlAllocateHeap(ProcessHeap,
558 0,
559 (Length + 1) * sizeof(WCHAR));
560 if (Entry->SourceFileName == NULL)
561 {
562 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
564 return FALSE;
565 }
566 RtlStringCchCopyW(Entry->SourceFileName, Length + 1, SourceFileName);
567 }
568
569 /* Copy optional target directory */
570 Entry->TargetDirectory = NULL;
571 if (TargetPath != NULL)
572 {
573 Length = wcslen(TargetPath);
574 if ((Length > 0) && (TargetPath[Length - 1] == L'\\'))
575 Length--;
576 Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap,
577 0,
578 (Length + 1) * sizeof(WCHAR));
579 if (Entry->TargetDirectory == NULL)
580 {
581 if (Entry->SourceFileName != NULL)
582 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
583
584 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
586 return FALSE;
587 }
588 RtlStringCchCopyW(Entry->TargetDirectory, Length + 1, TargetPath);
589 }
590
591 /* Copy target filename */
592 Length = wcslen(TargetFileName);
593 Entry->TargetFileName = RtlAllocateHeap(ProcessHeap,
594 0,
595 (Length + 1) * sizeof(WCHAR));
596 if (Entry->TargetFileName == NULL)
597 {
598 if (Entry->TargetDirectory != NULL)
599 RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
600
601 if (Entry->SourceFileName != NULL)
602 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
603
604 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
606 return FALSE;
607 }
608 RtlStringCchCopyW(Entry->TargetFileName, Length + 1, TargetFileName);
609
610 /* Append the queue entry */
611 InsertTailList(&QueueHeader->RenameQueue, &Entry->ListEntry);
612 ++QueueHeader->RenameCount;
613
614 return TRUE;
615}

Variable Documentation

◆ SpFileQueueClose

Definition at line 1001 of file fileqsup.c.

Referenced by DoFileCopy().

◆ SpFileQueueCommit

Definition at line 1005 of file fileqsup.c.

Referenced by DoFileCopy().

◆ SpFileQueueCopy

Definition at line 1002 of file fileqsup.c.

Referenced by AddSectionToCopyQueue(), and AddSectionToCopyQueueCab().

◆ SpFileQueueDelete

Definition at line 1003 of file fileqsup.c.

◆ SpFileQueueOpen

Definition at line 1000 of file fileqsup.c.

Referenced by PrepareFileCopy().

◆ SpFileQueueRename

Definition at line 1004 of file fileqsup.c.