buildframework/helium/external/filedisk/exe/filedisk.c
changeset 179 d8ac696cc51f
parent 1 be27ed110b50
child 180 e02a83d4c571
child 592 3215c239276a
equal deleted inserted replaced
1:be27ed110b50 179:d8ac696cc51f
     1 /*
       
     2     Control program for a virtual disk driver for Windows NT/2000/XP.
       
     3     Copyright (C) 1999, 2000, 2001, 2002 Bo Brantén.
       
     4     This program is free software; you can redistribute it and/or modify
       
     5     it under the terms of the GNU General Public License as published by
       
     6     the Free Software Foundation; either version 2 of the License, or
       
     7     (at your option) any later version.
       
     8     This program is distributed in the hope that it will be useful,
       
     9     but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    11     GNU General Public License for more details.
       
    12     You should have received a copy of the GNU General Public License
       
    13     along with this program; if not, write to the Free Software
       
    14     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    15 */
       
    16 
       
    17 #include <windows.h>
       
    18 #include <winioctl.h>
       
    19 #include <stdio.h>
       
    20 #include <stdlib.h>
       
    21 #include "filedisk.h"
       
    22 
       
    23 int FileDiskSyntax(void)
       
    24 {
       
    25     fprintf(stderr, "syntax:\n");
       
    26     fprintf(stderr, "filedisk /mount  <devicenumber> <filename> [size[k|M|G] | /ro | /cd] <drive:>\n");
       
    27     fprintf(stderr, "filedisk /umount <drive:>\n");
       
    28     fprintf(stderr, "filedisk /status <drive:>\n");
       
    29     fprintf(stderr, "\n");
       
    30     fprintf(stderr, "filename formats:\n");
       
    31     fprintf(stderr, "  c:\\path\\filedisk.img\n");
       
    32     fprintf(stderr, "  \\Device\\Harddisk0\\Partition1\\path\\filedisk.img\n");
       
    33     fprintf(stderr, "  \\\\server\\share\\path\\filedisk.img\n");
       
    34     fprintf(stderr, "\n");
       
    35     fprintf(stderr, "example:\n");
       
    36     fprintf(stderr, "filedisk /mount  0 c:\\temp\\filedisk.img 8M f:\n");
       
    37     fprintf(stderr, "filedisk /mount  1 c:\\temp\\cdimage.iso /cd i:\n");
       
    38     fprintf(stderr, "filedisk /umount f:\n");
       
    39     fprintf(stderr, "filedisk /umount i:\n");
       
    40 
       
    41     return -1;
       
    42 }
       
    43 
       
    44 void PrintLastError(char* Prefix)
       
    45 {
       
    46     LPVOID lpMsgBuf;
       
    47 
       
    48     FormatMessage( 
       
    49         FORMAT_MESSAGE_ALLOCATE_BUFFER |
       
    50         FORMAT_MESSAGE_FROM_SYSTEM |
       
    51         FORMAT_MESSAGE_IGNORE_INSERTS,
       
    52         NULL,
       
    53         GetLastError(),
       
    54         0,
       
    55         (LPTSTR) &lpMsgBuf,
       
    56         0,
       
    57         NULL
       
    58         );
       
    59 
       
    60     fprintf(stderr, "%s %s", Prefix, (LPTSTR) lpMsgBuf);
       
    61 
       
    62     LocalFree(lpMsgBuf);
       
    63 }
       
    64 
       
    65 int
       
    66 FileDiskMount(
       
    67     int                     DeviceNumber,
       
    68     POPEN_FILE_INFORMATION  OpenFileInformation,
       
    69     char                    DriveLetter,
       
    70     BOOLEAN                 CdImage
       
    71 )
       
    72 {
       
    73     char    VolumeName[] = "\\\\.\\ :";
       
    74     char    DeviceName[255];
       
    75     HANDLE  Device;
       
    76     DWORD   BytesReturned;
       
    77 
       
    78     VolumeName[4] = DriveLetter;
       
    79 
       
    80     Device = CreateFile(
       
    81         VolumeName,
       
    82         GENERIC_READ | GENERIC_WRITE,
       
    83         FILE_SHARE_READ | FILE_SHARE_WRITE,
       
    84         NULL,
       
    85         OPEN_EXISTING,
       
    86         FILE_FLAG_NO_BUFFERING,
       
    87         NULL
       
    88         );
       
    89 
       
    90     if (Device != INVALID_HANDLE_VALUE)
       
    91     {
       
    92         SetLastError(ERROR_BUSY);
       
    93         PrintLastError(&VolumeName[4]);
       
    94         return -1;
       
    95     }
       
    96 
       
    97     if (CdImage)
       
    98     {
       
    99         sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
       
   100     }
       
   101     else
       
   102     {
       
   103         sprintf(DeviceName, DEVICE_NAME_PREFIX "%u", DeviceNumber);
       
   104     }
       
   105 
       
   106     if (!DefineDosDevice(
       
   107         DDD_RAW_TARGET_PATH,
       
   108         &VolumeName[4],
       
   109         DeviceName
       
   110         ))
       
   111     {
       
   112         PrintLastError(&VolumeName[4]);
       
   113         return -1;
       
   114     }
       
   115 
       
   116     Device = CreateFile(
       
   117         VolumeName,
       
   118         GENERIC_READ | GENERIC_WRITE,
       
   119         FILE_SHARE_READ | FILE_SHARE_WRITE,
       
   120         NULL,
       
   121         OPEN_EXISTING,
       
   122         FILE_FLAG_NO_BUFFERING,
       
   123         NULL
       
   124         );
       
   125 
       
   126     if (Device == INVALID_HANDLE_VALUE)
       
   127     {
       
   128         PrintLastError(&VolumeName[4]);
       
   129         DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
       
   130         return -1;
       
   131     }
       
   132 
       
   133     if (!DeviceIoControl(
       
   134         Device,
       
   135         IOCTL_FILE_DISK_OPEN_FILE,
       
   136         OpenFileInformation,
       
   137         sizeof(OPEN_FILE_INFORMATION) + OpenFileInformation->FileNameLength - 1,
       
   138         NULL,
       
   139         0,
       
   140         &BytesReturned,
       
   141         NULL
       
   142         ))
       
   143     {
       
   144         PrintLastError("FileDisk:");
       
   145         DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
       
   146         return -1;
       
   147     }
       
   148 
       
   149     return 0;
       
   150 }
       
   151 
       
   152 int FileDiskUmount(char DriveLetter)
       
   153 {
       
   154     char    VolumeName[] = "\\\\.\\ :";
       
   155     HANDLE  Device;
       
   156     DWORD   BytesReturned;
       
   157 
       
   158     VolumeName[4] = DriveLetter;
       
   159 
       
   160     Device = CreateFile(
       
   161         VolumeName,
       
   162         GENERIC_READ | GENERIC_WRITE,
       
   163         FILE_SHARE_READ | FILE_SHARE_WRITE,
       
   164         NULL,
       
   165         OPEN_EXISTING,
       
   166         FILE_FLAG_NO_BUFFERING,
       
   167         NULL
       
   168         );
       
   169 
       
   170     if (Device == INVALID_HANDLE_VALUE)
       
   171     {
       
   172         PrintLastError(&VolumeName[4]);
       
   173         return -1;
       
   174     }
       
   175 
       
   176     if (!DeviceIoControl(
       
   177         Device,
       
   178         FSCTL_LOCK_VOLUME,
       
   179         NULL,
       
   180         0,
       
   181         NULL,
       
   182         0,
       
   183         &BytesReturned,
       
   184         NULL
       
   185         ))
       
   186     {
       
   187         PrintLastError(&VolumeName[4]);
       
   188         return -1;
       
   189     }
       
   190 
       
   191     if (!DeviceIoControl(
       
   192         Device,
       
   193         IOCTL_FILE_DISK_CLOSE_FILE,
       
   194         NULL,
       
   195         0,
       
   196         NULL,
       
   197         0,
       
   198         &BytesReturned,
       
   199         NULL
       
   200         ))
       
   201     {
       
   202         PrintLastError("FileDisk:");
       
   203         return -1;
       
   204     }
       
   205 
       
   206     if (!DeviceIoControl(
       
   207         Device,
       
   208         FSCTL_DISMOUNT_VOLUME,
       
   209         NULL,
       
   210         0,
       
   211         NULL,
       
   212         0,
       
   213         &BytesReturned,
       
   214         NULL
       
   215         ))
       
   216     {
       
   217         PrintLastError(&VolumeName[4]);
       
   218         return -1;
       
   219     }
       
   220 
       
   221     if (!DeviceIoControl(
       
   222         Device,
       
   223         FSCTL_UNLOCK_VOLUME,
       
   224         NULL,
       
   225         0,
       
   226         NULL,
       
   227         0,
       
   228         &BytesReturned,
       
   229         NULL
       
   230         ))
       
   231     {
       
   232         PrintLastError(&VolumeName[4]);
       
   233         return -1;
       
   234     }
       
   235 
       
   236     CloseHandle(Device);
       
   237 
       
   238     if (!DefineDosDevice(
       
   239         DDD_REMOVE_DEFINITION,
       
   240         &VolumeName[4],
       
   241         NULL
       
   242         ))
       
   243     {
       
   244         PrintLastError(&VolumeName[4]);
       
   245         return -1;
       
   246     }
       
   247 
       
   248     return 0;
       
   249 }
       
   250 
       
   251 int FileDiskStatus(char DriveLetter)
       
   252 {
       
   253     char                    VolumeName[] = "\\\\.\\ :";
       
   254     HANDLE                  Device;
       
   255     POPEN_FILE_INFORMATION  OpenFileInformation;
       
   256     DWORD                   BytesReturned;
       
   257 
       
   258     VolumeName[4] = DriveLetter;
       
   259 
       
   260     Device = CreateFile(
       
   261         VolumeName,
       
   262         GENERIC_READ,
       
   263         FILE_SHARE_READ | FILE_SHARE_WRITE,
       
   264         NULL,
       
   265         OPEN_EXISTING,
       
   266         FILE_FLAG_NO_BUFFERING,
       
   267         NULL
       
   268         );
       
   269 
       
   270     if (Device == INVALID_HANDLE_VALUE)
       
   271     {
       
   272         PrintLastError(&VolumeName[4]);
       
   273         return -1;
       
   274     }
       
   275 
       
   276     OpenFileInformation = malloc(sizeof(OPEN_FILE_INFORMATION) + MAX_PATH);
       
   277 
       
   278     if (!DeviceIoControl(
       
   279         Device,
       
   280         IOCTL_FILE_DISK_QUERY_FILE,
       
   281         NULL,
       
   282         0,
       
   283         OpenFileInformation,
       
   284         sizeof(OPEN_FILE_INFORMATION) + MAX_PATH,
       
   285         &BytesReturned,
       
   286         NULL
       
   287         ))
       
   288     {
       
   289         PrintLastError(&VolumeName[4]);
       
   290         return -1;
       
   291     }
       
   292 
       
   293     if (BytesReturned < sizeof(OPEN_FILE_INFORMATION))
       
   294     {
       
   295         SetLastError(ERROR_INSUFFICIENT_BUFFER);
       
   296         PrintLastError(&VolumeName[4]);
       
   297         return -1;
       
   298     }
       
   299 
       
   300     printf("%c: %.*s Size: %I64u bytes%s\n",
       
   301         DriveLetter,
       
   302         OpenFileInformation->FileNameLength,
       
   303         OpenFileInformation->FileName,
       
   304         OpenFileInformation->FileSize,
       
   305         OpenFileInformation->ReadOnly ? ", ReadOnly" : ""
       
   306         );
       
   307 
       
   308     return 0;
       
   309 }
       
   310 
       
   311 int __cdecl main(int argc, char* argv[])
       
   312 {
       
   313     char*                   Command;
       
   314     int                     DeviceNumber;
       
   315     char*                   FileName;
       
   316     char*                   Option;
       
   317     char                    DriveLetter;
       
   318     BOOLEAN                 CdImage = FALSE;
       
   319     POPEN_FILE_INFORMATION  OpenFileInformation;
       
   320 
       
   321     Command = argv[1];
       
   322 
       
   323     if ((argc == 5 || argc == 6) && !strcmp(Command, "/mount"))
       
   324     {
       
   325         DeviceNumber = atoi(argv[2]);
       
   326         FileName = argv[3];
       
   327 
       
   328         if (strlen(FileName) < 2)
       
   329         {
       
   330             return FileDiskSyntax();
       
   331         }
       
   332 
       
   333         OpenFileInformation =
       
   334             malloc(sizeof(OPEN_FILE_INFORMATION) + strlen(FileName) + 7);
       
   335 
       
   336         memset(
       
   337             OpenFileInformation,
       
   338             0,
       
   339             sizeof(OPEN_FILE_INFORMATION) + strlen(FileName) + 7
       
   340             );
       
   341 
       
   342         if (FileName[0] == '\\')
       
   343         {
       
   344             if (FileName[1] == '\\')
       
   345                 // \\server\share\path\filedisk.img
       
   346             {
       
   347                 strcpy(OpenFileInformation->FileName, "\\??\\UNC");
       
   348                 strcat(OpenFileInformation->FileName, FileName + 1);
       
   349             }
       
   350             else
       
   351                 // \Device\Harddisk0\Partition1\path\filedisk.img
       
   352             {
       
   353                 strcpy(OpenFileInformation->FileName, FileName);
       
   354             }
       
   355         }
       
   356         else
       
   357             // c:\path\filedisk.img
       
   358         {
       
   359             strcpy(OpenFileInformation->FileName, "\\??\\");
       
   360             strcat(OpenFileInformation->FileName, FileName);
       
   361         }
       
   362 
       
   363         OpenFileInformation->FileNameLength =
       
   364             (USHORT) strlen(OpenFileInformation->FileName);
       
   365 
       
   366         if (argc > 5)
       
   367         {
       
   368             Option = argv[4];
       
   369             DriveLetter = argv[5][0];
       
   370 
       
   371             if (!strcmp(Option, "/ro"))
       
   372             {
       
   373                 OpenFileInformation->ReadOnly = TRUE;
       
   374             }
       
   375             else if (!strcmp(Option, "/cd"))
       
   376             {
       
   377                 CdImage = TRUE;
       
   378             }
       
   379             else
       
   380             {
       
   381                 if (Option[strlen(Option) - 1] == 'G')
       
   382                 {
       
   383                     OpenFileInformation->FileSize.QuadPart =
       
   384                         _atoi64(Option) * 1024 * 1024 * 1024;
       
   385                 }
       
   386                 else if (Option[strlen(Option) - 1] == 'M')
       
   387                 {
       
   388                     OpenFileInformation->FileSize.QuadPart =
       
   389                         _atoi64(Option) * 1024 * 1024;
       
   390                 }
       
   391                 else if (Option[strlen(Option) - 1] == 'k')
       
   392                 {
       
   393                     OpenFileInformation->FileSize.QuadPart =
       
   394                         _atoi64(Option) * 1024;
       
   395                 }
       
   396                 else
       
   397                 {
       
   398                     OpenFileInformation->FileSize.QuadPart =
       
   399                         _atoi64(Option);
       
   400                 }
       
   401             }
       
   402         }
       
   403         else
       
   404         {
       
   405             DriveLetter = argv[4][0];
       
   406         }
       
   407         return FileDiskMount(DeviceNumber, OpenFileInformation, DriveLetter, CdImage);
       
   408     }
       
   409     else if (argc == 3 && !strcmp(Command, "/umount"))
       
   410     {
       
   411         DriveLetter = argv[2][0];
       
   412         return FileDiskUmount(DriveLetter);
       
   413     }
       
   414     else if (argc == 3 && !strcmp(Command, "/status"))
       
   415     {
       
   416         DriveLetter = argv[2][0];
       
   417         return FileDiskStatus(DriveLetter);
       
   418     }
       
   419     else
       
   420     {
       
   421         return FileDiskSyntax();
       
   422     }
       
   423 }