Exemple #1
0
NTSTATUS
SetupExtractFile(
    PWCHAR CabinetFileName,
    PWCHAR SourceFileName,
    PWCHAR DestinationPathName)
{
    ULONG CabStatus;

    DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n",
           CabinetFileName, SourceFileName, DestinationPathName);

    if (HasCurrentCabinet)
    {
        DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName);
    }

    if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) == 0))
    {
        DPRINT("Using same cabinet as last time\n");

        /* Use our last location because the files should be sequential */
        CabStatus = CabinetFindNextFileSequential(SourceFileName, &Search);
        if (CabStatus != CAB_STATUS_SUCCESS)
        {
            DPRINT("Sequential miss on file: %S\n", SourceFileName);

            /* Looks like we got unlucky */
            CabStatus = CabinetFindFirst(SourceFileName, &Search);
        }
    }
    else
    {
        DPRINT("Using new cabinet\n");

        if (HasCurrentCabinet)
        {
            CabinetCleanup();
        }

        wcscpy(CurrentCabinetName, CabinetFileName);

        CabinetInitialize();
        CabinetSetEventHandlers(NULL, NULL, NULL);
        CabinetSetCabinetName(CabinetFileName);

        CabStatus = CabinetOpen();
        if (CabStatus == CAB_STATUS_SUCCESS)
        {
            DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
            HasCurrentCabinet = TRUE;
        }
        else
        {
            DPRINT("Cannot open cabinet (%d)\n", CabStatus);
            return STATUS_UNSUCCESSFUL;
        }

        /* We have to start at the beginning here */
        CabStatus = CabinetFindFirst(SourceFileName, &Search);
    }

    if (CabStatus != CAB_STATUS_SUCCESS)
    {
        DPRINT1("Unable to find '%S' in cabinet '%S'\n", SourceFileName, CabinetGetCabinetName());
        return STATUS_UNSUCCESSFUL;
    }

    CabinetSetDestinationPath(DestinationPathName);
    CabStatus = CabinetExtractFile(&Search);
    if (CabStatus != CAB_STATUS_SUCCESS)
    {
        DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus);
        return STATUS_UNSUCCESSFUL;
    }

    return STATUS_SUCCESS;
}
Exemple #2
0
/*
 * FUNCTION: Finds next file in the cabinet that matches a search criteria
 * ARGUMENTS:
 *     Search = Pointer to search structure
 * RETURNS:
 *     Status of operation
 */
ULONG
CabinetFindNext(PCAB_SEARCH Search)
{
    ULONG Status;
    PCFFILE Prev;
    ANSI_STRING AnsiString;
    UNICODE_STRING UnicodeString;
    WCHAR FileName[MAX_PATH];

    if (wcscmp(Search->Cabinet, CabinetName) != 0)
    {
        /* restart search of cabinet has changed since last find */
        Search->File = 0;
    }

    if (!Search->File)
    {
        /* starting new search or cabinet */
        Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset);
        Search->Index = 0;
        Prev = 0;
    }
    else
        Prev = Search->File;

    while (TRUE)
    {
        /* look at each file in the archive and see if we found a match */
        if (Search->File->FolderIndex == 0xFFFD ||
            Search->File->FolderIndex == 0xFFFF)
        {
            /* skip files continued from previous cab */
            DPRINT("Skipping file (%s): FileOffset (0x%X), "
                   "LastFileOffset (0x%X)\n", (char *)(Search->File + 1),
                   Search->File->FileOffset, LastFileOffset);
        }
        else
        {
            // FIXME: check for match against search criteria
            if (Search->File != Prev)
            {
                /* don't match the file we started with */
                if (wcscmp(Search->Search, L"*") == 0)
                {
                    /* take any file */
                    break;
                }
                else
                {
                    /* otherwise, try to match the exact file name */
                    RtlInitAnsiString(&AnsiString, Search->File->FileName);
                    UnicodeString.Buffer = FileName;
                    UnicodeString.Buffer[0] = 0;
                    UnicodeString.Length = 0;
                    UnicodeString.MaximumLength = sizeof(FileName);
                    RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
                    if (wcscmp(Search->Search, UnicodeString.Buffer) == 0)
                        break;
                }
            }
        }

        /* if we make it here we found no match, so move to the next file */
        Search->Index++;
        if (Search->Index >= PCABHeader->FileCount)
        {
            /* we have reached the end of this cabinet, try to open the next */
            DPRINT("End of cabinet reached\n");
            if (wcslen(DiskNext) > 0)
            {
                CloseCabinet();

                CabinetSetCabinetName(CabinetNext);
                wcscpy(Search->Cabinet, CabinetName);

                if (DiskChangeHandler != NULL)
                {
                    DiskChangeHandler(CabinetNext, DiskNext);
                }

                Status = CabinetOpen();
                if (Status != CAB_STATUS_SUCCESS)
                    return Status;
            }
            else
            {
                return CAB_STATUS_NOFILE;
            }

            /* starting new search or cabinet */
            Search->File = (PCFFILE)(FileBuffer + PCABHeader->FileTableOffset);
            Search->Index = 0;
            Prev = 0;
        }
        else
            Search->File = (PCFFILE)(strchr((char *)(Search->File + 1), 0) + 1);
    }

    DPRINT("Found file %s\n", Search->File->FileName);
    return CAB_STATUS_SUCCESS;
}