Пример #1
0
int parse_url( int history_file, double filever, int currrecoff, char *delim, int filesize, char *type, std::vector< URLRec * > &urls  ) {
  char fourbytes[4];
  char hashrecflagsstr[4];
  char eightbytes[8];
  char chr;
  int filenameoff;
  int httpheadersoff;
  int urloff;
  int i;
  int reclen;
  int dirnameoff;
  time_t modtime;
  time_t accesstime;
  char ascmodtime[26], ascaccesstime[26];
  char dirname[9];
  char *url;
  char *filename;
  char *httpheaders;
  int year, mon;
  struct tm *accesstm, *modtm;

  pread( history_file, fourbytes, 4, currrecoff+4 );
  reclen = bah_to_i( fourbytes, 4 )*BLOCK_SIZE; 

  pread( history_file, eightbytes, 8, currrecoff+8 );
  modtime = win_time_to_unix( eightbytes );
  
  pread( history_file, eightbytes, 8, currrecoff+16 );
  accesstime = win_time_to_unix( eightbytes );
 
  accesstm = localtime( &accesstime );
  year = accesstm->tm_year + 1900;
  mon = accesstm->tm_mon + 1;
  sprintf( ascaccesstime, "%02d/%02d/%02d %02d:%02d:%02d", mon, accesstm->tm_mday, year, accesstm->tm_hour, accesstm->tm_min, accesstm->tm_sec );

  modtm = localtime( &modtime );
  year = modtm->tm_year + 1900;
  mon = modtm->tm_mon + 1;
  sprintf( ascmodtime, "%02d/%02d/%02d %02d:%02d:%02d", mon, modtm->tm_mday, year, modtm->tm_hour, modtm->tm_min, modtm->tm_sec );
  
  if (accesstime == 0) {
    ascaccesstime[0] = '\0';
  }

  if (modtime == 0) {
    ascmodtime[0] = '\0';
  }
  
  url = (char *)malloc( reclen+1 );

  if (filever >= 5) {
    pread( history_file, &chr, 1, currrecoff+0x34 );
  } else {
    pread( history_file, &chr, 1, currrecoff+0x38 );    
  }
  urloff = (unsigned char)chr;

  i = 0;
  pread( history_file, &chr, 1, currrecoff+urloff );
  while ( chr != '\0' && currrecoff+urloff+i+1 < filesize ) {
    url[i] = chr;
    pread( history_file, &chr, 1, currrecoff+urloff+i+1 );
    i++; 
  } 
  url[i] = '\0';

  filename = (char *)malloc( reclen+1 );

  if (filever >= 5) {
    pread( history_file, fourbytes, 4, currrecoff+0x3C );
  } else {
    pread( history_file, fourbytes, 4, currrecoff+0x40 );
  }
  filenameoff = bah_to_i( fourbytes, 4 ) + currrecoff; 

  i = 0;
  if (filenameoff > currrecoff+0x3C) {
    pread( history_file, &chr, 1, filenameoff );
    while ( chr != '\0' && filenameoff+i+1 < filesize ) {
      filename[i] = chr;
      pread( history_file, &chr, 1, filenameoff+i+1 );
      i++; 
    } 
  }
  filename[i] = '\0';

  if (filever >= 5.2) {
    pread( history_file, &chr, 1, currrecoff+0x38 );
  } else if (filever >= 5) {
    pread( history_file, &chr, 1, currrecoff+0x39 );
  } else {
    pread( history_file, &chr, 1, currrecoff+0x3C );
  }
  dirnameoff = (unsigned char)chr;

  if (0x50+(12*dirnameoff)+8 < filesize) {
    pread( history_file, dirname, 8, 0x50+(12*dirnameoff) );
    dirname[8] = '\0';
  } else {
    dirname[0] = '\0';
  }

  httpheaders = (char *)malloc( reclen+1 );

  if (filever >= 5) {
    pread( history_file, fourbytes, 4, currrecoff+0x44 );
  } else {
    pread( history_file, fourbytes, 4, currrecoff+0x48 );
  }
  httpheadersoff = bah_to_i( fourbytes, 4 ) + currrecoff; 

  i = 0;
  if (httpheadersoff > currrecoff+0x44) {
    pread( history_file, &chr, 1, httpheadersoff );

    while ( chr != '\0' && httpheadersoff+i+1 < currrecoff+reclen && httpheadersoff+i+1 < filesize ) {
      httpheaders[i] = chr;
      pread( history_file, &chr, 1, httpheadersoff+i+1 );
      i++; 
    }
  } 
  httpheaders[i] = '\0';
 
  printablestring( type );
  printablestring( url );
  printablestring( ascmodtime );
  printablestring( ascaccesstime );
  printablestring( filename );
  printablestring( dirname );
  printablestring( httpheaders );

  if (type[3] == ' ') {
    type[3] = '\0';
  }

  URLRec *urlrec = new URLRec(type, url, ascmodtime, ascaccesstime, filename, dirname, httpheaders);
  urls.push_back(urlrec);


  type[0] = '\0';
  dirname[0] = '\0';
  ascmodtime[0] = '\0';
  ascaccesstime[0] = '\0';

  free( url );
  free( filename );
  free( httpheaders );
}
Пример #2
0
static NTSTATUS query_dir_item(fcb* fcb, ccb* ccb, void* buf, LONG* len, PIRP Irp, dir_entry* de, root* r) {
    PIO_STACK_LOCATION IrpSp;
    LONG needed;
    UINT64 inode;
    INODE_ITEM ii;
    NTSTATUS Status;
    ULONG atts = 0, ealen = 0;
    file_ref* fileref = ccb->fileref;

    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    if (de->key.obj_type == TYPE_ROOT_ITEM) { // subvol
        LIST_ENTRY* le;

        r = NULL;

        le = fcb->Vcb->roots.Flink;
        while (le != &fcb->Vcb->roots) {
            root* subvol = CONTAINING_RECORD(le, root, list_entry);

            if (subvol->id == de->key.obj_id) {
                r = subvol;
                break;
            }

            le = le->Flink;
        }

        if (r && r->parent != fcb->subvol->id)
            r = NULL;

        inode = SUBVOL_ROOT_INODE;
    } else {
        inode = de->key.obj_id;
    }

    if (IrpSp->Parameters.QueryDirectory.FileInformationClass != FileNamesInformation) { // FIXME - object ID and reparse point classes too?
        switch (de->dir_entry_type) {
            case DirEntryType_File:
            {
                if (!r) {
                    LARGE_INTEGER time;

                    ii = fcb->Vcb->dummy_fcb->inode_item;
                    atts = fcb->Vcb->dummy_fcb->atts;
                    ealen = fcb->Vcb->dummy_fcb->ealen;

                    KeQuerySystemTime(&time);
                    win_time_to_unix(time, &ii.otime);
                    ii.st_atime = ii.st_mtime = ii.st_ctime = ii.otime;
                } else {
                    BOOL found = FALSE;

                    if (de->dc && de->dc->fileref && de->dc->fileref->fcb) {
                        ii = de->dc->fileref->fcb->inode_item;
                        atts = de->dc->fileref->fcb->atts;
                        ealen = de->dc->fileref->fcb->ealen;
                        found = TRUE;
                    }

                    if (!found) {
                        KEY searchkey;
                        traverse_ptr tp;

                        searchkey.obj_id = inode;
                        searchkey.obj_type = TYPE_INODE_ITEM;
                        searchkey.offset = 0xffffffffffffffff;

                        Status = find_item(fcb->Vcb, r, &tp, &searchkey, FALSE, Irp);
                        if (!NT_SUCCESS(Status)) {
                            ERR("error - find_item returned %08x\n", Status);
                            return Status;
                        }

                        if (tp.item->key.obj_id != searchkey.obj_id || tp.item->key.obj_type != searchkey.obj_type) {
                            ERR("could not find inode item for inode %llx in root %llx\n", inode, r->id);
                            return STATUS_INTERNAL_ERROR;
                        }

                        RtlZeroMemory(&ii, sizeof(INODE_ITEM));

                        if (tp.item->size > 0)
                            RtlCopyMemory(&ii, tp.item->data, min(sizeof(INODE_ITEM), tp.item->size));

                        if (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileFullDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdFullDirectoryInformation) {

                            BOOL dotfile = de->name.Length > sizeof(WCHAR) && de->name.Buffer[0] == '.';

                            atts = get_file_attributes(fcb->Vcb, r, inode, de->type, dotfile, FALSE, Irp);
                        }

                        if (IrpSp->Parameters.QueryDirectory.FileInformationClass == FileBothDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileFullDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdBothDirectoryInformation ||
                            IrpSp->Parameters.QueryDirectory.FileInformationClass == FileIdFullDirectoryInformation) {
                            ealen = get_ea_len(fcb->Vcb, r, inode, Irp);
                        }
                    }
                }

                break;
            }

            case DirEntryType_Self:
                ii = fcb->inode_item;
                r = fcb->subvol;
                inode = fcb->inode;
                atts = fcb->atts;
                ealen = fcb->ealen;
                break;

            case DirEntryType_Parent:
                if (fileref && fileref->parent) {
                    ii = fileref->parent->fcb->inode_item;
                    r = fileref->parent->fcb->subvol;
                    inode = fileref->parent->fcb->inode;
                    atts = fileref->parent->fcb->atts;
                    ealen = fileref->parent->fcb->ealen;
                } else {
                    ERR("no fileref\n");
                    return STATUS_INTERNAL_ERROR;
                }
                break;
        }

        if (atts == 0)
            atts = FILE_ATTRIBUTE_NORMAL;
    }

    switch (IrpSp->Parameters.QueryDirectory.FileInformationClass) {
        case FileBothDirectoryInformation:
        {
            FILE_BOTH_DIR_INFORMATION* fbdi = buf;

            TRACE("FileBothDirectoryInformation\n");

            needed = sizeof(FILE_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;

            if (needed > *len) {
                TRACE("buffer overflow - %u > %u\n", needed, *len);
                return STATUS_BUFFER_OVERFLOW;
            }

            fbdi->NextEntryOffset = 0;
            fbdi->FileIndex = 0;
            fbdi->CreationTime.QuadPart = unix_time_to_win(&ii.otime);
            fbdi->LastAccessTime.QuadPart = unix_time_to_win(&ii.st_atime);
            fbdi->LastWriteTime.QuadPart = unix_time_to_win(&ii.st_mtime);
            fbdi->ChangeTime.QuadPart = unix_time_to_win(&ii.st_ctime);
            fbdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;

            if (de->type == BTRFS_TYPE_SYMLINK)
                fbdi->AllocationSize.QuadPart = 0;
            else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
                fbdi->AllocationSize.QuadPart = ii.st_blocks;
            else
                fbdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);

            fbdi->FileAttributes = atts;
            fbdi->FileNameLength = de->name.Length;
            fbdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
            fbdi->ShortNameLength = 0;

            RtlCopyMemory(fbdi->FileName, de->name.Buffer, de->name.Length);

            *len -= needed;

            return STATUS_SUCCESS;
        }

        case FileDirectoryInformation:
        {
            FILE_DIRECTORY_INFORMATION* fdi = buf;

            TRACE("FileDirectoryInformation\n");

            needed = sizeof(FILE_DIRECTORY_INFORMATION) - sizeof(WCHAR) + de->name.Length;

            if (needed > *len) {
                TRACE("buffer overflow - %u > %u\n", needed, *len);
                return STATUS_BUFFER_OVERFLOW;
            }

            fdi->NextEntryOffset = 0;
            fdi->FileIndex = 0;
            fdi->CreationTime.QuadPart = unix_time_to_win(&ii.otime);
            fdi->LastAccessTime.QuadPart = unix_time_to_win(&ii.st_atime);
            fdi->LastWriteTime.QuadPart = unix_time_to_win(&ii.st_mtime);
            fdi->ChangeTime.QuadPart = unix_time_to_win(&ii.st_ctime);
            fdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;

            if (de->type == BTRFS_TYPE_SYMLINK)
                fdi->AllocationSize.QuadPart = 0;
            else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
                fdi->AllocationSize.QuadPart = ii.st_blocks;
            else
                fdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);

            fdi->FileAttributes = atts;
            fdi->FileNameLength = de->name.Length;

            RtlCopyMemory(fdi->FileName, de->name.Buffer, de->name.Length);

            *len -= needed;

            return STATUS_SUCCESS;
        }

        case FileFullDirectoryInformation:
        {
            FILE_FULL_DIR_INFORMATION* ffdi = buf;

            TRACE("FileFullDirectoryInformation\n");

            needed = sizeof(FILE_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;

            if (needed > *len) {
                TRACE("buffer overflow - %u > %u\n", needed, *len);
                return STATUS_BUFFER_OVERFLOW;
            }

            ffdi->NextEntryOffset = 0;
            ffdi->FileIndex = 0;
            ffdi->CreationTime.QuadPart = unix_time_to_win(&ii.otime);
            ffdi->LastAccessTime.QuadPart = unix_time_to_win(&ii.st_atime);
            ffdi->LastWriteTime.QuadPart = unix_time_to_win(&ii.st_mtime);
            ffdi->ChangeTime.QuadPart = unix_time_to_win(&ii.st_ctime);
            ffdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;

            if (de->type == BTRFS_TYPE_SYMLINK)
                ffdi->AllocationSize.QuadPart = 0;
            else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
                ffdi->AllocationSize.QuadPart = ii.st_blocks;
            else
                ffdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);

            ffdi->FileAttributes = atts;
            ffdi->FileNameLength = de->name.Length;
            ffdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;

            RtlCopyMemory(ffdi->FileName, de->name.Buffer, de->name.Length);

            *len -= needed;

            return STATUS_SUCCESS;
        }

        case FileIdBothDirectoryInformation:
        {
            FILE_ID_BOTH_DIR_INFORMATION* fibdi = buf;

            TRACE("FileIdBothDirectoryInformation\n");

            needed = sizeof(FILE_ID_BOTH_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;

            if (needed > *len) {
                TRACE("buffer overflow - %u > %u\n", needed, *len);
                return STATUS_BUFFER_OVERFLOW;
            }

            fibdi->NextEntryOffset = 0;
            fibdi->FileIndex = 0;
            fibdi->CreationTime.QuadPart = unix_time_to_win(&ii.otime);
            fibdi->LastAccessTime.QuadPart = unix_time_to_win(&ii.st_atime);
            fibdi->LastWriteTime.QuadPart = unix_time_to_win(&ii.st_mtime);
            fibdi->ChangeTime.QuadPart = unix_time_to_win(&ii.st_ctime);
            fibdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;

            if (de->type == BTRFS_TYPE_SYMLINK)
                fibdi->AllocationSize.QuadPart = 0;
            else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
                fibdi->AllocationSize.QuadPart = ii.st_blocks;
            else
                fibdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);

            fibdi->FileAttributes = atts;
            fibdi->FileNameLength = de->name.Length;
            fibdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
            fibdi->ShortNameLength = 0;
            fibdi->FileId.QuadPart = r ? make_file_id(r, inode) : make_file_id(fcb->Vcb->dummy_fcb->subvol, fcb->Vcb->dummy_fcb->inode);

            RtlCopyMemory(fibdi->FileName, de->name.Buffer, de->name.Length);

            *len -= needed;

            return STATUS_SUCCESS;
        }

        case FileIdFullDirectoryInformation:
        {
            FILE_ID_FULL_DIR_INFORMATION* fifdi = buf;

            TRACE("FileIdFullDirectoryInformation\n");

            needed = sizeof(FILE_ID_FULL_DIR_INFORMATION) - sizeof(WCHAR) + de->name.Length;

            if (needed > *len) {
                TRACE("buffer overflow - %u > %u\n", needed, *len);
                return STATUS_BUFFER_OVERFLOW;
            }

            fifdi->NextEntryOffset = 0;
            fifdi->FileIndex = 0;
            fifdi->CreationTime.QuadPart = unix_time_to_win(&ii.otime);
            fifdi->LastAccessTime.QuadPart = unix_time_to_win(&ii.st_atime);
            fifdi->LastWriteTime.QuadPart = unix_time_to_win(&ii.st_mtime);
            fifdi->ChangeTime.QuadPart = unix_time_to_win(&ii.st_ctime);
            fifdi->EndOfFile.QuadPart = de->type == BTRFS_TYPE_SYMLINK ? 0 : ii.st_size;

            if (de->type == BTRFS_TYPE_SYMLINK)
                fifdi->AllocationSize.QuadPart = 0;
            else if (atts & FILE_ATTRIBUTE_SPARSE_FILE)
                fifdi->AllocationSize.QuadPart = ii.st_blocks;
            else
                fifdi->AllocationSize.QuadPart = sector_align(ii.st_size, fcb->Vcb->superblock.sector_size);

            fifdi->FileAttributes = atts;
            fifdi->FileNameLength = de->name.Length;
            fifdi->EaSize = (r && atts & FILE_ATTRIBUTE_REPARSE_POINT) ? get_reparse_tag(fcb->Vcb, r, inode, de->type, atts, ccb->lxss, Irp) : ealen;
            fifdi->FileId.QuadPart = r ? make_file_id(r, inode) : make_file_id(fcb->Vcb->dummy_fcb->subvol, fcb->Vcb->dummy_fcb->inode);

            RtlCopyMemory(fifdi->FileName, de->name.Buffer, de->name.Length);

            *len -= needed;

            return STATUS_SUCCESS;
        }

        case FileNamesInformation:
        {
            FILE_NAMES_INFORMATION* fni = buf;

            TRACE("FileNamesInformation\n");

            needed = sizeof(FILE_NAMES_INFORMATION) - sizeof(WCHAR) + de->name.Length;

            if (needed > *len) {
                TRACE("buffer overflow - %u > %u\n", needed, *len);
                return STATUS_BUFFER_OVERFLOW;
            }

            fni->NextEntryOffset = 0;
            fni->FileIndex = 0;
            fni->FileNameLength = de->name.Length;

            RtlCopyMemory(fni->FileName, de->name.Buffer, de->name.Length);

            *len -= needed;

            return STATUS_SUCCESS;
        }

        case FileObjectIdInformation:
            FIXME("STUB: FileObjectIdInformation\n");
            return STATUS_NOT_IMPLEMENTED;

        case FileQuotaInformation:
            FIXME("STUB: FileQuotaInformation\n");
            return STATUS_NOT_IMPLEMENTED;

        case FileReparsePointInformation:
            FIXME("STUB: FileReparsePointInformation\n");
            return STATUS_NOT_IMPLEMENTED;

        default:
            WARN("Unknown FileInformationClass %u\n", IrpSp->Parameters.QueryDirectory.FileInformationClass);
            return STATUS_NOT_IMPLEMENTED;
    }

    return STATUS_NO_MORE_FILES;
}