[build] Move userland utility into subdir
[people/sha0/winvblock.git] / src / util / mount.c
1 /**
2  * Copyright 2006-2008, V.
3  * Portions copyright (C) 2009, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
4  * For WinAoE contact information, see http://winaoe.org/
5  *
6  * This file is part of WinVBlock, derived from WinAoE.
7  *
8  * WinVBlock is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * WinVBlock is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with WinVBlock.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 /**
23  * @file
24  *
25  * Mount command
26  *
27  */
28
29 #include <windows.h>
30 #include <winioctl.h>
31 #include <stdio.h>
32
33 #include "../winvblock.h"
34 #include "../portable.h"
35 #include "../mount.h"
36
37 typedef enum
38 { CommandScan, CommandShow, CommandMount, CommandUmount, CommandAttach,
39   CommandDetach
40 } COMMAND;
41
42 static void
43 Help (
44   void
45  )
46 {
47   printf ( "winvblk <scan|show|mount|umount|attach|detach>\n\n" );
48   printf ( "  scan\n        Shows the reachable AoE targets.\n\n" );
49   printf ( "  show\n        Shows the mounted AoE targets.\n\n" );
50   printf ( "  mount <client mac address> <major> <minor>\n"
51            "        Mounts an AoE target.\n\n" );
52   printf ( "  umount <disk number>\n        Unmounts an AoE disk.\n\n" );
53   printf ( "  attach <filepath> <disk type> <cyls> <heads> <sectors>\n"
54            "        Attaches <filepath> disk image file.\n"
55            "        <disk type> is 'f' for floppy, 'c' for CD/DVD, "
56            "'h' for HDD\n\n" );
57   printf ( "  detach <disk number>\n"
58            "        Detaches file-backed disk.\n\n" );
59 }
60
61 int
62 main (
63   int argc,
64   char **argv,
65   char **envp
66  )
67 {
68   COMMAND Command;
69   HANDLE DeviceHandle;
70   winvblock__uint8 InBuffer[sizeof ( mount__filedisk ) + 1024];
71   winvblock__uint8 String[256];
72   PMOUNT_TARGETS Targets;
73   PMOUNT_DISKS Disks;
74   winvblock__uint8 Mac[6];
75   DWORD BytesReturned;
76   winvblock__uint32 Major,
77    Minor,
78    Disk;
79   winvblock__uint32 i;
80
81   if ( argc < 2 )
82     {
83       Help (  );
84       goto end;
85     }
86
87   if ( strcmp ( argv[1], "scan" ) == 0 )
88     {
89       Command = CommandScan;
90     }
91   else if ( strcmp ( argv[1], "show" ) == 0 )
92     {
93       Command = CommandShow;
94     }
95   else if ( strcmp ( argv[1], "mount" ) == 0 )
96     {
97       Command = CommandMount;
98     }
99   else if ( strcmp ( argv[1], "umount" ) == 0 )
100     {
101       Command = CommandUmount;
102     }
103   else if ( strcmp ( argv[1], "attach" ) == 0 )
104     {
105       Command = CommandAttach;
106     }
107   else if ( strcmp ( argv[1], "detach" ) == 0 )
108     {
109       Command = CommandDetach;
110     }
111   else
112     {
113       Help (  );
114       printf ( "Press enter to exit\n" );
115       getchar (  );
116       goto end;
117     }
118
119   DeviceHandle =
120     CreateFile ( "\\\\.\\" winvblock__literal, GENERIC_READ | GENERIC_WRITE,
121                  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0,
122                  NULL );
123   if ( DeviceHandle == INVALID_HANDLE_VALUE )
124     {
125       printf ( "CreateFile (%d)\n", ( int )GetLastError (  ) );
126       goto end;
127     }
128
129   switch ( Command )
130     {
131       case CommandScan:
132         if ( ( Targets =
133                ( PMOUNT_TARGETS ) malloc ( sizeof ( MOUNT_TARGETS ) +
134                                            ( 32 *
135                                              sizeof ( MOUNT_TARGET ) ) ) ) ==
136              NULL )
137           {
138             printf ( "Out of memory\n" );
139             break;
140           }
141         if ( !DeviceIoControl
142              ( DeviceHandle, IOCTL_AOE_SCAN, NULL, 0, Targets,
143                ( sizeof ( MOUNT_TARGETS ) + ( 32 * sizeof ( MOUNT_TARGET ) ) ),
144                &BytesReturned, ( LPOVERLAPPED ) NULL ) )
145           {
146             printf ( "DeviceIoControl (%d)\n", ( int )GetLastError (  ) );
147             free ( Targets );
148             break;
149           }
150         if ( Targets->Count == 0 )
151           {
152             printf ( "No AoE targets found.\n" );
153           }
154         else
155           {
156             printf
157               ( "Client NIC          Target      Server MAC         Size\n" );
158             for ( i = 0; i < Targets->Count && i < 10; i++ )
159               {
160                 sprintf ( String, "e%lu.%lu      ", Targets->Target[i].Major,
161                           Targets->Target[i].Minor );
162                 String[10] = 0;
163                 printf
164                   ( " %02x:%02x:%02x:%02x:%02x:%02x  %s  %02x:%02x:%02x:%02x:%02x:%02x  %I64uM\n",
165                     Targets->Target[i].ClientMac[0],
166                     Targets->Target[i].ClientMac[1],
167                     Targets->Target[i].ClientMac[2],
168                     Targets->Target[i].ClientMac[3],
169                     Targets->Target[i].ClientMac[4],
170                     Targets->Target[i].ClientMac[5], String,
171                     Targets->Target[i].ServerMac[0],
172                     Targets->Target[i].ServerMac[1],
173                     Targets->Target[i].ServerMac[2],
174                     Targets->Target[i].ServerMac[3],
175                     Targets->Target[i].ServerMac[4],
176                     Targets->Target[i].ServerMac[5],
177                     ( Targets->Target[i].LBASize / 2048 ) );
178               }
179           }
180         free ( Targets );
181         printf ( "Press enter to exit\n" );
182         getchar (  );
183         break;
184       case CommandShow:
185         if ( ( Disks =
186                ( PMOUNT_DISKS ) malloc ( sizeof ( MOUNT_DISKS ) +
187                                          ( 32 * sizeof ( MOUNT_DISK ) ) ) ) ==
188              NULL )
189           {
190             printf ( "Out of memory\n" );
191             break;
192           }
193         if ( !DeviceIoControl
194              ( DeviceHandle, IOCTL_AOE_SHOW, NULL, 0, Disks,
195                ( sizeof ( MOUNT_DISKS ) + ( 32 * sizeof ( MOUNT_DISK ) ) ),
196                &BytesReturned, ( LPOVERLAPPED ) NULL ) )
197           {
198             printf ( "DeviceIoControl (%d)\n", ( int )GetLastError (  ) );
199             free ( Disks );
200             break;
201           }
202         if ( Disks->Count == 0 )
203           {
204             printf ( "No AoE disks mounted.\n" );
205           }
206         else
207           {
208             printf
209               ( "Disk  Client NIC         Server MAC         Target      Size\n" );
210             for ( i = 0; i < Disks->Count && i < 10; i++ )
211               {
212                 sprintf ( String, "e%lu.%lu      ", Disks->Disk[i].Major,
213                           Disks->Disk[i].Minor );
214                 String[10] = 0;
215                 printf
216                   ( " %-4lu %02x:%02x:%02x:%02x:%02x:%02x  %02x:%02x:%02x:%02x:%02x:%02x  %s  %I64uM\n",
217                     Disks->Disk[i].Disk, Disks->Disk[i].ClientMac[0],
218                     Disks->Disk[i].ClientMac[1], Disks->Disk[i].ClientMac[2],
219                     Disks->Disk[i].ClientMac[3], Disks->Disk[i].ClientMac[4],
220                     Disks->Disk[i].ClientMac[5], Disks->Disk[i].ServerMac[0],
221                     Disks->Disk[i].ServerMac[1], Disks->Disk[i].ServerMac[2],
222                     Disks->Disk[i].ServerMac[3], Disks->Disk[i].ServerMac[4],
223                     Disks->Disk[i].ServerMac[5], String,
224                     ( Disks->Disk[i].LBASize / 2048 ) );
225               }
226           }
227         free ( Disks );
228         printf ( "Press enter to exit\n" );
229         getchar (  );
230         break;
231       case CommandMount:
232         sscanf ( argv[2], "%02x:%02x:%02x:%02x:%02x:%02x", ( int * )&Mac[0],
233                  ( int * )&Mac[1], ( int * )&Mac[2], ( int * )&Mac[3],
234                  ( int * )&Mac[4], ( int * )&Mac[5] );
235         sscanf ( argv[3], "%d", ( int * )&Major );
236         sscanf ( argv[4], "%d", ( int * )&Minor );
237         printf ( "mounting e%d.%d from %02x:%02x:%02x:%02x:%02x:%02x\n",
238                  ( int )Major, ( int )Minor, Mac[0], Mac[1], Mac[2], Mac[3],
239                  Mac[4], Mac[5] );
240         memcpy ( &InBuffer[0], Mac, 6 );
241         *( winvblock__uint16_ptr ) ( &InBuffer[6] ) =
242           ( winvblock__uint16 ) Major;
243         *( winvblock__uint8_ptr ) ( &InBuffer[8] ) =
244           ( winvblock__uint8 ) Minor;
245         if ( !DeviceIoControl
246              ( DeviceHandle, IOCTL_AOE_MOUNT, InBuffer, sizeof ( InBuffer ),
247                NULL, 0, &BytesReturned, ( LPOVERLAPPED ) NULL ) )
248           {
249             printf ( "DeviceIoControl (%d)\n", ( int )GetLastError (  ) );
250           }
251         break;
252       case CommandUmount:
253         sscanf ( argv[2], "%d", ( int * )&Disk );
254         printf ( "unmounting disk %d\n", ( int )Disk );
255         memcpy ( &InBuffer, &Disk, 4 );
256         if ( !DeviceIoControl
257              ( DeviceHandle, IOCTL_AOE_UMOUNT, InBuffer, sizeof ( InBuffer ),
258                NULL, 0, &BytesReturned, ( LPOVERLAPPED ) NULL ) )
259           {
260             printf ( "DeviceIoControl (%d)\n", ( int )GetLastError (  ) );
261           }
262         break;
263       case CommandAttach:
264         {
265           mount__filedisk filedisk;
266           char obj_path_prefix[] = "\\??\\";
267
268           if ( argc < 6 )
269             {
270               printf ( "Too few parameters.\n" );
271               Help (  );
272               CloseHandle ( DeviceHandle );
273               return 1;
274             }
275           filedisk.type = *argv[3];
276           sscanf ( argv[4], "%d", ( int * )&filedisk.cylinders );
277           sscanf ( argv[5], "%d", ( int * )&filedisk.heads );
278           sscanf ( argv[6], "%d", ( int * )&filedisk.sectors );
279           memcpy ( &InBuffer, &filedisk, sizeof ( mount__filedisk ) );
280           memcpy ( &InBuffer[sizeof ( mount__filedisk )], obj_path_prefix,
281                    sizeof ( obj_path_prefix ) );
282           memcpy ( &InBuffer
283                    [sizeof ( mount__filedisk ) + sizeof ( obj_path_prefix ) -
284                     1], argv[2], strlen ( argv[2] ) + 1 );
285           if ( !DeviceIoControl
286                ( DeviceHandle, IOCTL_FILE_ATTACH, InBuffer,
287                  sizeof ( InBuffer ), NULL, 0, &BytesReturned,
288                  ( LPOVERLAPPED ) NULL ) )
289             {
290               printf ( "DeviceIoControl (%d)\n", ( int )GetLastError (  ) );
291             }
292           break;
293         }
294       case CommandDetach:
295         sscanf ( argv[2], "%d", ( int * )&Disk );
296         printf ( "Detaching file-backed disk %d\n", ( int )Disk );
297         memcpy ( &InBuffer, &Disk, 4 );
298         if ( !DeviceIoControl
299              ( DeviceHandle, IOCTL_FILE_DETACH, InBuffer, sizeof ( InBuffer ),
300                NULL, 0, &BytesReturned, ( LPOVERLAPPED ) NULL ) )
301           {
302             printf ( "DeviceIoControl (%d)\n", ( int )GetLastError (  ) );
303           }
304         break;
305     }
306   CloseHandle ( DeviceHandle );
307
308 end:
309   return 0;
310 }