7
7
#include < imapi2fs.h>
8
8
#include < imapi2fserror.h>
9
9
10
- // Found on net under the name of iampi2.cpp See also imapi2sample.cpp in WDK
10
+ // Based what found on net under the name of iampi2.cpp. See also imapi2sample.cpp in WSDK
11
11
12
12
#pragma comment(lib, "ole32.lib")
13
13
#pragma comment(lib, "shlwapi.lib")
14
14
15
+ // supported UDF (latest is 2.60) :
16
+ // 258 = 1.02 Most consumer devices
17
+ // 336 = 1.50 Win2K
18
+ // 512 = 2.00
19
+ // 513 = 2.01 XP
20
+ // 592 = 2.50 Vista
21
+ // MediaType (from cd to bluray)
22
+ // Bluray = UDF 2.50
23
+ // DVD = UDF 1.02
24
+ // Except for CD (ISO+Joliet+UDF), FS always UDF only
25
+ // under XP HDDVD always failed
26
+ // under XP if media not choosen, default is CD
27
+ // media selection decide max iso size
28
+ // Thus important media type for iso data image is CD, DVDDL and BD
29
+
15
30
int main (int argc, char ** argv) {
16
- HRESULT hres = 0 ;
31
+ HRESULT hr = 0 ;
17
32
CoInitialize (NULL );
18
33
IFileSystemImage* image = NULL ;
19
34
IFileSystemImageResult* result = NULL ;
20
35
IFsiDirectoryItem* root = NULL ;
21
36
IStream* bootfile = NULL ;
22
37
wchar_t * bootfilename;
23
- IStream* r_i = NULL ;
38
+ IStream* isostream = NULL ;
24
39
IBootOptions *bootopt = NULL ;
25
40
EmulationType emul = EmulationNone;
26
41
int isbootable = 0 ;
27
42
STATSTG stg;
28
- FILE* f;
43
+ DWORD size;
44
+ DWORD written = 0 ;
45
+ HANDLE hFile;
46
+ BOOL bErrorFlag = FALSE ;
47
+ LONG numFiles = 0 ;
48
+ LONG numDirs = 0 ;
49
+ LONG numBlocks = 0 ;
50
+ unsigned int chunk = 536870912 ; // I dont know what to pick but somehow >1GB dont work
29
51
30
52
if (argc < 4 ) {
31
53
printf (" Usage:\n %s inrootdirectory outfile volname [bootfile emulation]\n " ,argv[0 ]);
32
54
printf (" emulation: None|12MFloppy|144MFloppy|288MFloppy|Harddisk\n " );
33
55
return 1 ;
34
56
}
35
57
wchar_t ** wargv = CommandLineToArgvW (GetCommandLineW (), &argc);
36
-
37
58
if (argc > 4 ) {
38
59
if (argc != 6 ) {
39
60
printf (" Both boot parameters must be specified\n " );
40
61
return 1 ;
41
62
}
42
- if (PathFileExistsW (wargv[4 ]) && !PathIsDirectoryW (wargv[4 ])) {
43
- bootfilename = wargv[4 ];
63
+ bootfilename = wargv[4 ];
44
64
if (wcsicmp (wargv[5 ], L" Harddisk" ) == 0 )
45
65
emul = EmulationHardDisk;
46
66
if (wcsicmp (wargv[5 ], L" 288MFloppy" ) == 0 )
@@ -49,72 +69,76 @@ int main(int argc, char ** argv) {
49
69
emul = Emulation144MFloppy;
50
70
if (wcsicmp (wargv[5 ], L" 12MFloppy" ) == 0 )
51
71
emul = Emulation12MFloppy;
52
- isbootable = 1 ;
53
- }
72
+ isbootable = 1 ;
54
73
}
55
-
56
- hres = CoCreateInstance (CLSID_MsftFileSystemImage, NULL , CLSCTX_ALL, __uuidof (IFileSystemImage), (void **)&image);
57
- if (SUCCEEDED (hres)) hres = image->put_UDFRevision (102 ); // set to min
58
- else { printf (" Init: Image failed\n " ); return 1 ; }
59
- if (FAILED (hres)) hres = image->put_UDFRevision (258 );
60
- if (SUCCEEDED (hres)) hres = image->put_FileSystemsToCreate ((FsiFileSystems)(FsiFileSystemJoliet | FsiFileSystemISO9660 | FsiFileSystemUDF ));
61
- else { printf (" Setting: UDF version failed\n " ); return 1 ; }
62
- if (FAILED (hres)) hres = image->put_FileSystemsToCreate ((FsiFileSystems)(FsiFileSystemJoliet | FsiFileSystemISO9660 ));
63
- if (SUCCEEDED (hres)) hres = image->put_VolumeName (wargv[3 ]);
64
- else { printf (" Setting: FS type failed\n " ); return 1 ; }
65
- if (SUCCEEDED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_BDR); // set to max
66
- else { printf (" Setting: Volume name as %S failed\n " , wargv[3 ]); return 1 ; }
67
- if (FAILED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_HDDVDR);
68
- if (FAILED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER);
69
- if (FAILED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER);
70
- if (FAILED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_DVDDASHR);
71
- if (FAILED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_DVDPLUSR);
72
- if (FAILED (hres)) hres = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_CDR);
73
- if (FAILED (hres)) printf (" Setting: Media type failed\n " ); // try keep continue
74
- hres = image->get_Root (&root);
74
+
75
+ hr = CoCreateInstance (CLSID_MsftFileSystemImage, NULL , CLSCTX_ALL, __uuidof (IFileSystemImage), (void **)&image);
76
+ if (SUCCEEDED (hr)) hr = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_BDR); // First, assign biggest media
77
+ else { printf (" Error: CoCreateInstance failed\n " ); exit (1 ); }
78
+ hr = image->put_VolumeName (wargv[3 ]);
79
+ if (SUCCEEDED (hr)) {
80
+ printf (" Collecting data...\n Volume name : %S\n " , wargv[3 ]);
81
+ hr = image->get_Root (&root);
82
+ } else exit (1 );
75
83
if (isbootable) {
76
- if (SUCCEEDED (hres)) hres = CoCreateInstance (CLSID_BootOptions, NULL , CLSCTX_ALL, __uuidof (IBootOptions), (void **)&bootopt);
77
- else { printf (" Init: Root failed\n " ); return 1 ; }
78
- if (SUCCEEDED (hres)) hres = SHCreateStreamOnFileW (bootfilename, STGM_READ | STGM_SHARE_DENY_WRITE, &bootfile);
79
- else { printf (" Init: Boot image failed\n " ); return 1 ; }
80
- if (SUCCEEDED (hres)) hres = bootopt->put_Emulation (emul);
81
- else { printf (" Setting: Getting boot file failed\n " ); return 1 ; }
82
- if (SUCCEEDED (hres)) hres = bootopt->put_PlatformId (PlatformX86);
83
- else { printf (" Setting: Boot emulation failed\n " ); return 1 ; }
84
- if (SUCCEEDED (hres)) hres = bootopt->AssignBootImage (bootfile);
85
- else { printf (" Setting: Boot platform failed\n " ); return 1 ; }
86
- if (SUCCEEDED (hres)) hres = image->put_BootImageOptions (bootopt);
87
- else { printf (" Setting: Assign boot file failed\n " ); return 1 ; }
84
+ if (SUCCEEDED (hr)) hr = CoCreateInstance (CLSID_BootOptions, NULL , CLSCTX_ALL, __uuidof (IBootOptions), (void **)&bootopt);
85
+ if (SUCCEEDED (hr)) hr = SHCreateStreamOnFileW (bootfilename, STGM_READ | STGM_SHARE_DENY_WRITE, &bootfile);
86
+ else { printf (" Error: CoCreateInstance failed\n " ); exit (1 ); }
87
+ if (SUCCEEDED (hr)) hr = bootopt->put_Emulation (emul);
88
+ else { printf (" Error: Getting boot file %s failed\n " , bootfilename); exit (1 ); }
89
+ if (SUCCEEDED (hr)) hr = bootopt->put_PlatformId (PlatformX86);
90
+ if (SUCCEEDED (hr)) hr = bootopt->AssignBootImage (bootfile);
91
+ if (SUCCEEDED (hr)) hr = image->put_BootImageOptions (bootopt);
92
+ else { printf (" Error: Assigning boot file failed\n " ); exit (1 ); }
93
+ }
94
+ if (SUCCEEDED (hr)) hr = root->AddTree (wargv[1 ], false );
95
+ if (FAILED (hr)) { printf (" Error: Adding content %S failed\n " , wargv[1 ]); exit (1 ); }
96
+ // find smallest (more compatible) media to fit
97
+ hr = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_CDR);
98
+ if (FAILED (hr)) {
99
+ hr = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_DVDDASHR);
100
+ if (FAILED (hr)) {
101
+ hr = image->ChooseImageDefaultsForMediaType (IMAPI_MEDIA_TYPE_BDR); // Back to BD
102
+ printf (" MediaType: Bluray (UDF 2.5)\n " );
103
+ }
104
+ else printf (" MediaType: DVD (UDF)\n " );
88
105
}
89
- if (SUCCEEDED (hres)) hres = root->AddTree (wargv[1 ], false );
90
- else { printf (" Setting: Boot image failed\n " ); return 1 ; }
91
- if (SUCCEEDED (hres)) hres = image->CreateResultImage (&result);
92
- else { printf (" Error: Adding content %S failed\n " , wargv[1 ]); return 1 ; }
93
- if (SUCCEEDED (hres)) hres = result->get_ImageStream (&r_i);
94
- else { printf (" Error: Building image failed\n " ); return 1 ; }
106
+ else printf (" MediaType: CD (ISO9660+Joliet+UDF)\n " );
107
+ if (SUCCEEDED (hr)) hr = image->CreateResultImage (&result);
108
+ else { printf (" Error: Adding content %S failed\n " , wargv[1 ]); exit (1 ); }
109
+ if (SUCCEEDED (hr)) hr = result->get_ImageStream (&isostream);
95
110
96
- LONG numFiles = 0 ;
97
- LONG numDirs = 0 ;
98
- hres = image->get_FileCount (&numFiles);
99
- hres = image->get_DirectoryCount (&numDirs);
111
+ hFile = CreateFileW (wargv[2 ], GENERIC_WRITE, 0 , NULL , CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
112
+ if (hFile == INVALID_HANDLE_VALUE) {
113
+ printf (" Error: opening %S\n " ,wargv[2 ]);
114
+ exit (1 );
115
+ }
100
116
101
- printf (" Total: %d Folder(s) and %d File(s)" , numDirs, numFiles);
117
+ isostream->Stat (&stg, 1 );
118
+ if (stg.cbSize .QuadPart < (ULONGLONG)chunk)
119
+ chunk = stg.cbSize .QuadPart ;
102
120
103
- r_i->Stat (&stg, 1 );
104
- char * data = new char [stg.cbSize .QuadPart ];
105
- ULONG size;
106
- r_i->Read (data, stg.cbSize .QuadPart , &size);
121
+ char * data = new char [chunk];
122
+ do {
123
+ hr = isostream->Read (data, chunk, &size);
124
+ bErrorFlag = WriteFile (hFile, data, size, &written, NULL );
125
+ } while (SUCCEEDED (hr) && (TRUE == bErrorFlag) && (size > 0 ));
107
126
108
- f = _wfopen (wargv[2 ], L" wb" );
109
- if (f == NULL ) {
110
- printf (" Error opening %S\n " ,wargv[2 ]);
111
- return 1 ;
127
+ if (FALSE == bErrorFlag) {
128
+ printf (" Error: writing %S\n " ,wargv[3 ]);
129
+ CloseHandle (hFile);
130
+ DeleteFileW (wargv[3 ]);
131
+ exit (1 );
112
132
}
113
- fwrite (data, stg.cbSize .QuadPart , 1 , f);
114
- fclose (f);
115
-
133
+
134
+ result->get_TotalBlocks (&numBlocks);
135
+ image->get_FileCount (&numFiles);
136
+ image->get_DirectoryCount (&numDirs);
137
+ printf (" Total: %d Block(s), %d Folder(s) and %d File(s)\n Finished.\n " , numBlocks, numDirs, numFiles);
138
+ CloseHandle (hFile);
139
+
116
140
delete data;
117
- r_i ->Release ();
141
+ isostream ->Release ();
118
142
root->Release ();
119
143
result->Release ();
120
144
image->Release ();
0 commit comments