On Feb 8 16:30, Morph Ex wrote: > I'm trying to use "dd" to create a md5 checksum of a dvd. The problem > is that the number of records read by "dd" is always different > depending on the OS used. For example, using the same command below > in both cygwin and linux displays the following results. > > dd if=/dev/scd0 bs=2048 iflag=direct | md5sum -b > > Linux (ubuntu 8.10 amd64) > 28446caccede349759e4e9fed8bce862 > 3025539+0 records in > 3025539+0 records out > 6196303872 bytes (6.2 GB) copied, 3347.83 s, 1.9 MB/s > > Cygwin (windows xp pro) > 15cab8963c4746eca21c014224adefa3 > 3025538+0 records in > 3025538+0 records out > 6196301824 bytes (6.2 GB) copied, 3323.91 s, 1.9 MB/s
Just to let you know that I can reproduce a similar result. In my test case it's just not 1 block but 200 blocks. For some reason the Win32 function ReadFile returns EOF prematurely, in my case on XP as well as on Server 2008, and I have not the faintest idea why. I created a non-Cygwin testcase (attached) which uses only native NT functions to open/seek/read/close the device and it suffers the exact same problem. Ii doesn't have anything to do with Cygwin, apparently. If you want to experiment with the native NT testcase, you can build it with $ gcc -g -o ntreadraw ntreadraw.c -lntdll (with or without -mno-cygwin) and then you can run it like this: $ ./ntreadraw \\Device\\CdRom0 2048 3025530 The output for my testcase looks like this: $ ./ntreadraw \\Device\\CdRom0 2048 98990 partition info: offset 0 length 203044864 (99143 blocks) Setting offset to: 202731520 Current offset: 202731520 (block 98990) NtReadFile: pos: 202731520 (block 98990), status 0x00000000, bytes read: 2048 NtReadFile: pos: 202733568 (block 98991), status 0x00000000, bytes read: 2048 NtReadFile: pos: 202735616 (block 98992), status 0x00000000, bytes read: 2048 NtReadFile: pos: 202737664 (block 98993), status 0xc0000011, bytes read: 8 Final offset: 202737664 (block 98993) So in my case, the DVD has 99143 blocks and Windows stops to read after block 98993 all the time with status 0xC0000011, which simply is the native NT status code for EOF (STATUS_END_OF_FILE). I guess I'll ask on one of the Microsoft newsgroups if this is a known effect and especially what I'm doing wrong or what I have to do to get the desired behaviour. Btw., if anybody has an idea what's going wrong, please speak up :} Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Project Co-Leader cygwin AT cygwin DOT com Red Hat
#include <stdio.h> #include <inttypes.h> #include <windows.h> #include <ddk/ntifs.h> #include <ddk/winddk.h> #include <ddk/ntdddisk.h> #if defined (__CYGWIN__) || defined (__MINGW32__) #define NtDeviceIoControlFile ZwDeviceIoControlFile #define NtSetInformationFile ZwSetInformationFile #define NtQueryInformationFile ZwQueryInformationFile #endif BOOL NTAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR); int main (int argc, char **argv) { UNICODE_STRING upath; OBJECT_ATTRIBUTES attr; HANDLE h; IO_STATUS_BLOCK io; NTSTATUS status; PARTITION_INFORMATION_EX pix; FILE_POSITION_INFORMATION fpi; void *buf; ULONGLONG blocksize; ULONGLONG skip; if (argc < 4) { fprintf (stderr, "usage: %s native_path blocksize #_of_blocks_to_skip\n", argv[0]); return 1; } if (!RtlCreateUnicodeStringFromAsciiz (&upath, argv[1])) { fprintf (stderr, "RtlCreateUnicodeStringFromAsciiz failed\n"); return 1; } blocksize = strtoull (argv[2], NULL, 0); skip = strtoull (argv[3], NULL, 0); /* Open Device */ InitializeObjectAttributes (&attr, &upath, 0, NULL, NULL); status = NtOpenFile (&h, FILE_GENERIC_READ, &attr, &io, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS (status)) { fprintf (stderr, "NtOpenFile: 0x%08lx\n", status); return 1; } /* Get size information */ status = NtDeviceIoControlFile (h, NULL, NULL, NULL, &io, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &pix, sizeof pix); if (!NT_SUCCESS (status)) { fprintf (stderr, "NtDeviceIoControlFile: 0x%08lx\n", status); goto thats_all_folks; } printf ("partition info: offset %" PRId64 " length %" PRId64 " (%" PRId64 " blocks)\n", pix.StartingOffset.QuadPart, pix.PartitionLength.QuadPart, pix.PartitionLength.QuadPart / blocksize); /* Skip # of blocks given on the command line */ fpi.CurrentByteOffset.QuadPart = skip * blocksize; printf ("Setting offset to: %" PRId64 "\n", fpi.CurrentByteOffset.QuadPart); status = NtSetInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation); if (!NT_SUCCESS (status)) { fprintf (stderr, "NtSetInformationFile(%" PRId64 "): 0x%08lx\n", fpi.CurrentByteOffset.QuadPart, status); goto thats_all_folks; } /* First a check if we are where we want to be. */ fpi.CurrentByteOffset.QuadPart = 0; status = NtQueryInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation); if (!NT_SUCCESS (status)) { fprintf (stderr, "NtQueryInformationFile: 0x%08lx\n", status); goto thats_all_folks; } printf ("Current offset: %" PRId64 " (block %" PRId64 ")\n", fpi.CurrentByteOffset.QuadPart, fpi.CurrentByteOffset.QuadPart / blocksize); if (fpi.CurrentByteOffset.QuadPart != skip * blocksize) goto thats_all_folks; /* Now read until EOF or another error occured. */ buf = alloca (blocksize); status = 0; while (NT_SUCCESS (status)) { /* Missing status check but who cares? */ fpi.CurrentByteOffset.QuadPart = 0; NtQueryInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation); status = NtReadFile (h, NULL, NULL, NULL, &io, buf, blocksize, NULL, NULL); printf ("NtReadFile: pos: %" PRId64 " (block %" PRId64 "), status 0x%08lx, bytes read: %lu\n", fpi.CurrentByteOffset.QuadPart, fpi.CurrentByteOffset.QuadPart / blocksize, status, io.Information); Sleep (10L); } /* Final check for position. */ fpi.CurrentByteOffset.QuadPart = 0; status = NtQueryInformationFile (h, &io, &fpi, sizeof fpi, FilePositionInformation); if (!NT_SUCCESS (status)) { fprintf (stderr, "NtQueryInformationFile: 0x%08lx\n", status); goto thats_all_folks; } printf ("Final offset: %" PRId64 " (block %" PRId64 ")\n", fpi.CurrentByteOffset.QuadPart, fpi.CurrentByteOffset.QuadPart / blocksize); /* That's all folks. */ thats_all_folks: NtClose (h); return 0; }
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/