Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfilequeue.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* COPYRIGHT: See COPYING in the top level directory 00020 * PROJECT: ReactOS text-mode setup 00021 * FILE: subsys/system/usetup/filequeue.c 00022 * PURPOSE: File queue functions 00023 * PROGRAMMER: Eric Kohl 00024 * Casper S. Hornstrup (chorns@users.sourceforge.net) 00025 */ 00026 00027 /* INCLUDES *****************************************************************/ 00028 00029 #include "usetup.h" 00030 00031 #define NDEBUG 00032 #include <debug.h> 00033 00034 /* INCLUDES *****************************************************************/ 00035 00036 typedef struct _QUEUEENTRY 00037 { 00038 struct _QUEUEENTRY *Prev; 00039 struct _QUEUEENTRY *Next; 00040 00041 PWSTR SourceCabinet; /* May be NULL if file is not in a cabinet */ 00042 PWSTR SourceRootPath; 00043 PWSTR SourcePath; 00044 PWSTR SourceFilename; 00045 PWSTR TargetDirectory; 00046 PWSTR TargetFilename; 00047 00048 } QUEUEENTRY, *PQUEUEENTRY; 00049 00050 00051 typedef struct _FILEQUEUEHEADER 00052 { 00053 PQUEUEENTRY CopyHead; 00054 PQUEUEENTRY CopyTail; 00055 ULONG CopyCount; 00056 } FILEQUEUEHEADER, *PFILEQUEUEHEADER; 00057 00058 00059 /* FUNCTIONS ****************************************************************/ 00060 00061 HSPFILEQ WINAPI 00062 SetupOpenFileQueue(VOID) 00063 { 00064 PFILEQUEUEHEADER QueueHeader; 00065 00066 /* Allocate queue header */ 00067 QueueHeader = (PFILEQUEUEHEADER)RtlAllocateHeap(ProcessHeap, 00068 0, 00069 sizeof(FILEQUEUEHEADER)); 00070 if (QueueHeader == NULL) 00071 return(NULL); 00072 00073 /* Initialize queue header */ 00074 RtlZeroMemory(QueueHeader, 00075 sizeof(FILEQUEUEHEADER)); 00076 00077 00078 return((HSPFILEQ)QueueHeader); 00079 } 00080 00081 00082 VOID WINAPI 00083 SetupCloseFileQueue(HSPFILEQ QueueHandle) 00084 { 00085 PFILEQUEUEHEADER QueueHeader; 00086 PQUEUEENTRY Entry; 00087 00088 if (QueueHandle == NULL) 00089 return; 00090 00091 QueueHeader = (PFILEQUEUEHEADER)QueueHandle; 00092 00093 /* Delete copy queue */ 00094 Entry = QueueHeader->CopyHead; 00095 while (Entry != NULL) 00096 { 00097 /* Delete all strings */ 00098 if (Entry->SourceCabinet != NULL) 00099 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet); 00100 if (Entry->SourceRootPath != NULL) 00101 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); 00102 if (Entry->SourcePath != NULL) 00103 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); 00104 if (Entry->SourceFilename != NULL) 00105 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename); 00106 if (Entry->TargetDirectory != NULL) 00107 RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory); 00108 if (Entry->TargetFilename != NULL) 00109 RtlFreeHeap(ProcessHeap, 0, Entry->TargetFilename); 00110 00111 /* Unlink current queue entry */ 00112 if (Entry->Next != NULL) 00113 { 00114 QueueHeader->CopyHead = Entry->Next; 00115 QueueHeader->CopyHead->Prev = NULL; 00116 } 00117 else 00118 { 00119 QueueHeader->CopyHead = NULL; 00120 QueueHeader->CopyTail = NULL; 00121 } 00122 00123 /* Delete queue entry */ 00124 RtlFreeHeap(ProcessHeap, 0, Entry); 00125 00126 /* Get next queue entry */ 00127 Entry = QueueHeader->CopyHead; 00128 } 00129 00130 /* Delete queue header */ 00131 RtlFreeHeap(ProcessHeap, 00132 0, 00133 QueueHeader); 00134 } 00135 00136 00137 BOOL 00138 SetupQueueCopy(HSPFILEQ QueueHandle, 00139 PCWSTR SourceCabinet, 00140 PCWSTR SourceRootPath, 00141 PCWSTR SourcePath, 00142 PCWSTR SourceFilename, 00143 PCWSTR TargetDirectory, 00144 PCWSTR TargetFilename) 00145 { 00146 PFILEQUEUEHEADER QueueHeader; 00147 PQUEUEENTRY Entry; 00148 ULONG Length; 00149 00150 /* SourceCabinet may be NULL */ 00151 if (QueueHandle == NULL || 00152 SourceRootPath == NULL || 00153 SourceFilename == NULL || 00154 TargetDirectory == NULL) 00155 return(FALSE); 00156 00157 QueueHeader = (PFILEQUEUEHEADER)QueueHandle; 00158 00159 /* Allocate new queue entry */ 00160 Entry = (PQUEUEENTRY)RtlAllocateHeap(ProcessHeap, 00161 0, 00162 sizeof(QUEUEENTRY)); 00163 if (Entry == NULL) 00164 return(FALSE); 00165 00166 RtlZeroMemory(Entry, 00167 sizeof(QUEUEENTRY)); 00168 00169 /* Copy source cabinet if available */ 00170 if (SourceCabinet != NULL) 00171 { 00172 Length = wcslen(SourceCabinet); 00173 Entry->SourceCabinet = (WCHAR*) RtlAllocateHeap(ProcessHeap, 00174 0, 00175 (Length + 1) * sizeof(WCHAR)); 00176 if (Entry->SourceCabinet == NULL) 00177 { 00178 RtlFreeHeap(ProcessHeap, 0, Entry); 00179 return(FALSE); 00180 } 00181 wcsncpy(Entry->SourceCabinet, SourceCabinet, Length); 00182 Entry->SourceCabinet[Length] = (WCHAR)0; 00183 } 00184 else 00185 { 00186 Entry->SourceCabinet = NULL; 00187 } 00188 00189 /* Copy source root path */ 00190 Length = wcslen(SourceRootPath); 00191 Entry->SourceRootPath = (WCHAR*) RtlAllocateHeap(ProcessHeap, 00192 0, 00193 (Length + 1) * sizeof(WCHAR)); 00194 if (Entry->SourceRootPath == NULL) 00195 { 00196 if (Entry->SourceCabinet != NULL) 00197 { 00198 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet); 00199 } 00200 RtlFreeHeap(ProcessHeap, 0, Entry); 00201 return(FALSE); 00202 } 00203 wcsncpy(Entry->SourceRootPath, SourceRootPath, Length); 00204 Entry->SourceRootPath[Length] = (WCHAR)0; 00205 00206 /* Copy source path */ 00207 if (SourcePath != NULL) 00208 { 00209 Length = wcslen(SourcePath); 00210 Entry->SourcePath = (WCHAR*) RtlAllocateHeap(ProcessHeap, 00211 0, 00212 (Length + 1) * sizeof(WCHAR)); 00213 if (Entry->SourcePath == NULL) 00214 { 00215 if (Entry->SourceCabinet != NULL) 00216 { 00217 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet); 00218 } 00219 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); 00220 RtlFreeHeap(ProcessHeap, 0, Entry); 00221 return(FALSE); 00222 } 00223 wcsncpy(Entry->SourcePath, SourcePath, Length); 00224 Entry->SourcePath[Length] = (WCHAR)0; 00225 } 00226 00227 /* Copy source file name */ 00228 Length = wcslen(SourceFilename); 00229 Entry->SourceFilename = (WCHAR*) RtlAllocateHeap(ProcessHeap, 00230 0, 00231 (Length + 1) * sizeof(WCHAR)); 00232 if (Entry->SourceFilename == NULL) 00233 { 00234 if (Entry->SourceCabinet != NULL) 00235 { 00236 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet); 00237 } 00238 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); 00239 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); 00240 RtlFreeHeap(ProcessHeap, 0, Entry); 00241 return(FALSE); 00242 } 00243 wcsncpy(Entry->SourceFilename, SourceFilename, Length); 00244 Entry->SourceFilename[Length] = (WCHAR)0; 00245 00246 /* Copy target directory */ 00247 Length = wcslen(TargetDirectory); 00248 if (TargetDirectory[Length] == '\\') 00249 Length--; 00250 Entry->TargetDirectory = (WCHAR*) RtlAllocateHeap(ProcessHeap, 00251 0, 00252 (Length + 1) * sizeof(WCHAR)); 00253 if (Entry->TargetDirectory == NULL) 00254 { 00255 if (Entry->SourceCabinet != NULL) 00256 { 00257 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet); 00258 } 00259 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); 00260 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); 00261 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename); 00262 RtlFreeHeap(ProcessHeap, 0, Entry); 00263 return(FALSE); 00264 } 00265 wcsncpy(Entry->TargetDirectory, TargetDirectory, Length); 00266 Entry->TargetDirectory[Length] = (WCHAR)0; 00267 00268 /* Copy optional target filename */ 00269 if (TargetFilename != NULL) 00270 { 00271 Length = wcslen(TargetFilename); 00272 Entry->TargetFilename = (WCHAR*) RtlAllocateHeap(ProcessHeap, 00273 0, 00274 (Length + 1) * sizeof(WCHAR)); 00275 if (Entry->TargetFilename == NULL) 00276 { 00277 if (Entry->SourceCabinet != NULL) 00278 { 00279 RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet); 00280 } 00281 RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath); 00282 RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath); 00283 RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename); 00284 RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory); 00285 RtlFreeHeap(ProcessHeap, 0, Entry); 00286 return(FALSE); 00287 } 00288 wcsncpy(Entry->TargetFilename, TargetFilename, Length); 00289 Entry->TargetFilename[Length] = (WCHAR)0; 00290 } 00291 00292 /* Append queue entry */ 00293 if (QueueHeader->CopyHead == NULL) // && QueueHeader->CopyTail == NULL) 00294 { 00295 Entry->Prev = NULL; 00296 Entry->Next = NULL; 00297 QueueHeader->CopyHead = Entry; 00298 QueueHeader->CopyTail = Entry; 00299 } 00300 else 00301 { 00302 Entry->Prev = QueueHeader->CopyTail; 00303 Entry->Next = NULL; 00304 QueueHeader->CopyTail->Next = Entry; 00305 QueueHeader->CopyTail = Entry; 00306 } 00307 QueueHeader->CopyCount++; 00308 00309 return(TRUE); 00310 } 00311 00312 00313 BOOL WINAPI 00314 SetupCommitFileQueueW(HWND Owner, 00315 HSPFILEQ QueueHandle, 00316 PSP_FILE_CALLBACK_W MsgHandler, 00317 PVOID Context) 00318 { 00319 WCHAR CabinetName[MAX_PATH]; 00320 PFILEQUEUEHEADER QueueHeader; 00321 PQUEUEENTRY Entry; 00322 NTSTATUS Status; 00323 PCWSTR TargetRootPath, TargetPath; 00324 00325 WCHAR FileSrcPath[MAX_PATH]; 00326 WCHAR FileDstPath[MAX_PATH]; 00327 00328 TargetRootPath = ((PCOPYCONTEXT)Context)->DestinationRootPath; 00329 TargetPath = ((PCOPYCONTEXT)Context)->InstallPath; 00330 00331 if (QueueHandle == NULL) 00332 return(FALSE); 00333 00334 QueueHeader = (PFILEQUEUEHEADER)QueueHandle; 00335 00336 MsgHandler(Context, 00337 SPFILENOTIFY_STARTQUEUE, 00338 0, 00339 0); 00340 00341 MsgHandler(Context, 00342 SPFILENOTIFY_STARTSUBQUEUE, 00343 FILEOP_COPY, 00344 QueueHeader->CopyCount); 00345 00346 /* Commit copy queue */ 00347 Entry = QueueHeader->CopyHead; 00348 while (Entry != NULL) 00349 { 00350 wcscpy(FileSrcPath, Entry->SourceRootPath); 00351 if (Entry->SourcePath != NULL) 00352 wcscat(FileSrcPath, Entry->SourcePath); 00353 wcscat(FileSrcPath, L"\\"); 00354 wcscat(FileSrcPath, Entry->SourceFilename); 00355 00356 /* Build the full target path */ 00357 wcscpy(FileDstPath, TargetRootPath); 00358 if (Entry->TargetDirectory[0] == L'\\') 00359 { 00360 wcscat(FileDstPath, Entry->TargetDirectory); 00361 } 00362 else 00363 { 00364 if (TargetPath != NULL) 00365 { 00366 if (TargetPath[0] != L'\\') 00367 wcscat(FileDstPath, L"\\"); 00368 wcscat(FileDstPath, TargetPath); 00369 } 00370 wcscat(FileDstPath, L"\\"); 00371 wcscat(FileDstPath, Entry->TargetDirectory); 00372 } 00373 00374 /* Use only the destination path if the file is in a cabinet */ 00375 if (Entry->SourceCabinet == NULL) 00376 { 00377 wcscat(FileDstPath, L"\\"); 00378 if (Entry->TargetFilename != NULL) 00379 wcscat(FileDstPath, Entry->TargetFilename); 00380 else 00381 wcscat(FileDstPath, Entry->SourceFilename); 00382 } 00383 00384 /* FIXME: Do it! */ 00385 DPRINT("'%S' ==> '%S'\n", 00386 FileSrcPath, 00387 FileDstPath); 00388 00389 MsgHandler(Context, 00390 SPFILENOTIFY_STARTCOPY, 00391 (UINT_PTR)Entry->SourceFilename, 00392 FILEOP_COPY); 00393 00394 if (Entry->SourceCabinet != NULL) 00395 { 00396 /* Extract the file */ 00397 wcscpy(CabinetName, Entry->SourceRootPath); 00398 if (Entry->SourcePath != NULL) 00399 wcscat(CabinetName, Entry->SourcePath); 00400 wcscat(CabinetName, L"\\"); 00401 wcscat(CabinetName, Entry->SourceCabinet); 00402 Status = SetupExtractFile(CabinetName, Entry->SourceFilename, FileDstPath); 00403 } 00404 else 00405 { 00406 /* Copy the file */ 00407 Status = SetupCopyFile(FileSrcPath, FileDstPath); 00408 } 00409 if (!NT_SUCCESS(Status)) 00410 { 00411 MsgHandler(Context, 00412 SPFILENOTIFY_COPYERROR, 00413 (UINT_PTR)Entry->SourceFilename, 00414 FILEOP_COPY); 00415 00416 } 00417 else 00418 { 00419 MsgHandler(Context, 00420 SPFILENOTIFY_ENDCOPY, 00421 (UINT_PTR)Entry->SourceFilename, 00422 FILEOP_COPY); 00423 } 00424 00425 Entry = Entry->Next; 00426 } 00427 00428 MsgHandler(Context, 00429 SPFILENOTIFY_ENDSUBQUEUE, 00430 FILEOP_COPY, 00431 0); 00432 00433 MsgHandler(Context, 00434 SPFILENOTIFY_ENDQUEUE, 00435 0, 00436 0); 00437 00438 return(TRUE); 00439 } 00440 00441 /* EOF */ Generated on Sun May 27 2012 04:17:58 for ReactOS by
1.7.6.1
|