Solved

Sparse file help!

Posted on 2001-07-10
11
1,130 Views
Last Modified: 2013-12-03
Trying to mark a file as sparse, but keep getting an "Incorrect function" error. Relevant code:

DWORD dwAccess = GENERIC_WRITE;
m_hFile = CreateFile(m_strFilename,
                     dwAccess,
                     0,     // Exclusive access
                     NULL,
                     dwCreateFlag,
                     FILE_ATTRIBUTE_NORMAL,
                     NULL );

if( m_hFile == (HANDLE) INVALID_HANDLE_VALUE )
{
     RETURN_FILE_ERROR(_T("Unable to create Cache file"));
}

DWORD dwBytesReturned = 0;
QCHECK_RETURN( DeviceIoControl(
     m_hFile,            // handle to a file
     FSCTL_SET_SPARSE,   // dwIoControlCode operation
     NULL,               // lpInBuffer; must be NULL
     0,                  // nInBufferSize; must be zero
     NULL,               // lpOutBuffer; must be NULL
     0,                  // nOutBufferSize; must be zero
     &dwBytesReturned,   // number of bytes returned
     NULL                // OVERLAPPED structure
     ), E_FAIL );
     
I've tried a number of combinations of flags, to no avail.

The DeviceIoControl code is taken straight from the Platform SDK docs -- what could possibly be going wrong?

I'm on DevStudio sp5, Win2k sp1.


0
Comment
Question by:barrett
  • 5
  • 3
  • 2
  • +1
11 Comments
 
LVL 5

Expert Comment

by:robpitt
ID: 6270497
Never used it but it looks okay.
It is running on 2000 with NTFS, yes?

Rob
0
 

Author Comment

by:barrett
ID: 6270516
Yes, Win2k sp1 with NTFS. Can't find any documentation on the "incorrect function" error with sparse files.
0
 
LVL 5

Expert Comment

by:robpitt
ID: 6270905
Maybe for some unknown reason your NTFS doesn't support spare files. The only reason I can think of is because maybe the NTFS drive is marked as version 4 or maybe theres some system setting that inhibits use of sparse files - I don't know.

PS Does GetVolumeInformation() return the FILE_SUPPORTS_SPARSE_FILES flag?
0
 

Author Comment

by:barrett
ID: 6271122
It appears the volume supports sparse files:

TCHAR tzRootDir[MAX_PATH] = _T( "D:\\" );
TCHAR tzVolumeName[MAX_PATH] = _T( "\0" );
TCHAR tzFileSystemNameBuffer[MAX_PATH] = _T( "\0" );

DWORD dwFileSystemFlags = 0;
DWORD dwMaximumComponentLength = 0;
BOOL bRetVal = GetVolumeInformation(
     tzRootDir,                 // root directory
     tzVolumeName,              // volume name buffer
     MAX_PATH,                  // length of name buffer
     NULL,                      // volume serial number
     &dwMaximumComponentLength, // maximum file name length
     &dwFileSystemFlags,        // file system options
     tzFileSystemNameBuffer,    // file system name buffer
     MAX_PATH                   // length of file system name buffer
     );

ATLASSERT( dwFileSystemFlags & 0x000700ff );

This assertion succeeds, and tzFileSystemNameBuffer holds "NTFS".

0
 

Author Comment

by:barrett
ID: 6271126
er, that assertion should read:

ATLASSERT( dwFileSystemFlags & FILE_SUPPORTS_SPARSE_FILES );

The value of dwFileSystemFlags is 0x000700ff.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:barrett
ID: 6271419
INterestingly, the code straight out of MSDN fails the same way:

HANDLE h = CreateFile("A huge file.txt",
   GENERIC_WRITE, 0, NULL,
   CREATE_ALWAYS, 0, NULL);
DWORD dw;
DeviceIoControl(h, FSCTL_SET_SPARSE, NULL,
   0, NULL, 0, &dw, NULL);
LONG lDist = 8;   // 32 GB!!!
SetFilePointer(h, 0, &lDist, FILE_BEGIN);
SetEndOfFile(h);
CloseHandle(h);

So something must be wrong with my configuration. Haven't a clue what it could be.


0
 
LVL 15

Accepted Solution

by:
NickRepin earned 200 total points
ID: 6272525
This code works perfectly, the file created is 1.5M in size, the actual size on the disk is 500K.

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <winioctl.h>
#include <iostream.h>

void main(int argc,char* argv[])
{        
   if(argc<2)
   {
      cout<<"Usage: sparse  <drive_letter>"<<endl;
      return;
   }
   
   char buf[MAX_PATH]="G:\\\0est_sparse";
   buf[0]=argv[1][0];

   DWORD flags;
   if(!GetVolumeInformation(buf,0,0,0,0,&flags,0,0))
   {
      cout<<"Cannot GetVolumeInformation"<<endl;
      return;
   }

   cout<<"flags="<<hex<<flags<<dec<<endl;
   if(!(flags & FILE_SUPPORTS_SPARSE_FILES))
   {
      cout<<"Sparse files are not supported"<<endl;
   //   return;
   }

   buf[3]='t';
   cout<<buf<<endl;
   HANDLE hFile=CreateFile(buf,
      GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);
   if(hFile==INVALID_HANDLE_VALUE)
   {
      cout<<"Cannot create file "<<endl;
      return;
   }

   SetFilePointer(hFile,1500000,0,FILE_BEGIN);
   SetEndOfFile(hFile);


   DWORD dwBytesReturned = 0;
   if(!DeviceIoControl(hFile,FSCTL_SET_SPARSE,
      0,0,0,0,&dwBytesReturned,0))
   {
      cout<<"Cannot set sparce "<<GetLastError()<<endl;
      CloseHandle(hFile);
      return;
   }

   FILE_ZERO_DATA_INFORMATION zdi;
   zdi.FileOffset.LowPart=0;
   zdi.FileOffset.HighPart=0;
   zdi.BeyondFinalZero.LowPart=1000000;
   zdi.BeyondFinalZero.HighPart=0;
   if(!DeviceIoControl(hFile,FSCTL_SET_ZERO_DATA,
      &zdi,sizeof(zdi),0,0,&dwBytesReturned,0))
   {
      cout<<"Cannot zero data "<<GetLastError()<<endl;
      CloseHandle(hFile);
      return;
   }

   CloseHandle(hFile);
}

0
 
LVL 15

Expert Comment

by:NickRepin
ID: 6272536
I do not know what is QCHECK_RETURN(..., E_FAIL )

But I'm pretty sure that E_FAIL is 0x80004005L, which is neither TRUE nor FALSE.
0
 

Author Comment

by:barrett
ID: 6273249

Unfortunately this code fails the same way on both of my machines, "Incorrect function". This really is Win2k sp1 with an NTFS volume. What could possibly be going wrong?

I shouldn't have included that QCHECK_RETURN macro -- it's part of our shop's error-handling framework. Doesn't affect this test.
0
 
LVL 5

Expert Comment

by:robpitt
ID: 6273507
I give up!

You just seem to have a "special" machine that just will not let you use sparse files despite the fact that it should let you.
0
 

Expert Comment

by:geplauder
ID: 8114282
the same effect took me hours today.
A hint was "IOCTL: 0x980C4" from sysinternal's "File Monitor", where "fsutil sparse setflag" would just work.
I checked with winIOCTL.h (24APR98), which contains
#define FILE_DEVICE_FILE_SYSTEM         0x00000009
#define CTL_CODE(DeviceType, Function, Method, Access) \
    ((DeviceType)<<16) | ((Access)<<14) | ((Function)<<2) | (Method))
#define METHOD_BUFFERED                 0
#define FILE_WRITE_ACCESS         ( 0x0002 )    // file & pipe
#define FSCTL_SET_SPARSE                CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
giving the value above. I guessed DeviceType and Function were above suspicion, so I fiddled with access and method:
a "control code" of 0x900c4 seems to work fine. This corresponds to "FILE_ANY_ACCESS", I found "FILE_ACCESS_SPECIAL" with cygwin. I spent hours trying to track down english and german versions of VS6 & service packs: the english VS contains the same definitions, no service pack I ran into any winIOCTL.h at all. google found the above digit sequence in proximity with FSCTL_SET_SPARSE and VB. Is this one of those non-existant cases where installing a current service pack does not take you to the same state as installing all of them sequentially?
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
link access with Quickbooks 9 41
WPF MainWindow update textbox from another class... 6 102
Convert GUI app into console app for Win32 Env 5 82
Problem to file 3 67
This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

863 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

27 Experts available now in Live!

Get 1:1 Help Now