예제 #1
0
std::string Vpath::GetFilePath (std::string const & fileName)
{
    AppendFileName (fileName);
    std::string result = ToString ();
    RemoveFileName ();
    return result;
}
예제 #2
0
/*
 * FUNCTION: Opens a cabinet file
 * RETURNS:
 *     Status of operation
 */
ULONG
CabinetOpen(VOID)
{
    PUCHAR Buffer;
    UNICODE_STRING ustring;
    ANSI_STRING astring;

    if (!FileOpen)
    {
        OBJECT_ATTRIBUTES ObjectAttributes;
        IO_STATUS_BLOCK IoStatusBlock;
        UNICODE_STRING FileName;
        NTSTATUS NtStatus;
        ULONG Size;

        RtlInitUnicodeString(&FileName, CabinetName);

        InitializeObjectAttributes(&ObjectAttributes,
                                   &FileName,
                                   OBJ_CASE_INSENSITIVE,
                                   NULL, NULL);

        NtStatus = NtOpenFile(&FileHandle,
                              GENERIC_READ | SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              FILE_SHARE_READ,
                              FILE_SYNCHRONOUS_IO_NONALERT);

        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("Cannot open file (%S) (%x)\n", CabinetName, NtStatus);
            return CAB_STATUS_CANNOT_OPEN;
        }

        FileOpen = TRUE;

        NtStatus = NtCreateSection(&FileSectionHandle,
                                   SECTION_ALL_ACCESS,
                                   0, 0,
                                   PAGE_READONLY,
                                   SEC_COMMIT,
                                   FileHandle);

        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtCreateSection failed: %x\n", NtStatus);
            return CAB_STATUS_NOMEMORY;
        }

        FileBuffer = 0;
        FileSize = 0;

        NtStatus = NtMapViewOfSection(FileSectionHandle,
                                      NtCurrentProcess(),
                                      (PVOID *)&FileBuffer,
                                      0, 0, 0,
                                      &FileSize,
                                      ViewUnmap,
                                      0,
                                      PAGE_READONLY);

        if (!NT_SUCCESS(NtStatus))
        {
            DPRINT("NtMapViewOfSection failed: %x\n", NtStatus);
            return CAB_STATUS_NOMEMORY;
        }

        DPRINT("Cabinet file %S opened and mapped to %x\n", CabinetName, FileBuffer);
        PCABHeader = (PCFHEADER) FileBuffer;

        /* Check header */
        if (FileSize <= sizeof(CFHEADER) ||
            PCABHeader->Signature != CAB_SIGNATURE ||
            PCABHeader->Version != CAB_VERSION ||
            PCABHeader->FolderCount == 0 ||
            PCABHeader->FileCount == 0 ||
            PCABHeader->FileTableOffset < sizeof(CFHEADER))
        {
            CloseCabinet();
            DPRINT("File has invalid header\n");
            return CAB_STATUS_INVALID_CAB;
        }

        Size = 0;
        Buffer = (PUCHAR)(PCABHeader + 1);

        /* Read/skip any reserved bytes */
        if (PCABHeader->Flags & CAB_FLAG_RESERVE)
        {
            CabinetReserved = *(PUSHORT)Buffer;
            Buffer += 2;
            FolderReserved = *Buffer;
            Buffer++;
            DataReserved = *Buffer;
            Buffer++;

            if (CabinetReserved > 0)
            {
                CabinetReservedArea = Buffer;
                Buffer += CabinetReserved;
            }
        }

        if (PCABHeader->Flags & CAB_FLAG_HASPREV)
        {
            /* The previous cabinet file is in
               the same directory as the current */
            wcscpy(CabinetPrev, CabinetName);
            RemoveFileName(CabinetPrev);
            CabinetNormalizePath(CabinetPrev, 256);
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = wcslen(CabinetPrev);
            ustring.Buffer = CabinetPrev + ustring.Length;
            ustring.MaximumLength = sizeof(CabinetPrev) - ustring.Length;
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;

            /* Read label of prev disk */
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = 0;
            ustring.Buffer = DiskPrev;
            ustring.MaximumLength = sizeof(DiskPrev);
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;
        }
        else
        {
            wcscpy(CabinetPrev, L"");
            wcscpy(DiskPrev, L"");
        }

        if (PCABHeader->Flags & CAB_FLAG_HASNEXT)
        {
            /* The next cabinet file is in
               the same directory as the previous */
            wcscpy(CabinetNext, CabinetName);
            RemoveFileName(CabinetNext);
            CabinetNormalizePath(CabinetNext, 256);
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = wcslen(CabinetNext);
            ustring.Buffer = CabinetNext + ustring.Length;
            ustring.MaximumLength = sizeof(CabinetNext) - ustring.Length;
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;

            /* Read label of next disk */
            RtlInitAnsiString(&astring, (LPSTR)Buffer);
            ustring.Length = 0;
            ustring.Buffer = DiskNext;
            ustring.MaximumLength = sizeof(DiskNext);
            RtlAnsiStringToUnicodeString(&ustring, &astring, FALSE);
            Buffer += astring.Length + 1;
        }
        else
        {
            wcscpy(CabinetNext, L"");
            wcscpy(DiskNext, L"");
        }
        CabinetFolders = (PCFFOLDER)Buffer;
    }

    DPRINT("CabinetOpen returning SUCCESS\n");
    return CAB_STATUS_SUCCESS;
}