Skip to content

Commit 44bd6ce

Browse files
committed
Make isoimage works
1 parent 37c7bba commit 44bd6ce

File tree

2 files changed

+88
-64
lines changed

2 files changed

+88
-64
lines changed

isoimage.cpp

Lines changed: 88 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,60 @@
77
#include <imapi2fs.h>
88
#include <imapi2fserror.h>
99

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
1111

1212
#pragma comment(lib, "ole32.lib")
1313
#pragma comment(lib, "shlwapi.lib")
1414

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+
1530
int main(int argc, char ** argv) {
16-
HRESULT hres = 0;
31+
HRESULT hr = 0;
1732
CoInitialize(NULL);
1833
IFileSystemImage* image = NULL;
1934
IFileSystemImageResult* result = NULL;
2035
IFsiDirectoryItem* root = NULL;
2136
IStream* bootfile = NULL;
2237
wchar_t* bootfilename;
23-
IStream* r_i = NULL;
38+
IStream* isostream = NULL;
2439
IBootOptions *bootopt = NULL;
2540
EmulationType emul = EmulationNone;
2641
int isbootable = 0;
2742
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
2951

3052
if (argc < 4) {
3153
printf ("Usage:\n%s inrootdirectory outfile volname [bootfile emulation]\n",argv[0]);
3254
printf ("emulation: None|12MFloppy|144MFloppy|288MFloppy|Harddisk\n");
3355
return 1;
3456
}
3557
wchar_t** wargv = CommandLineToArgvW (GetCommandLineW(), &argc);
36-
3758
if (argc > 4) {
3859
if (argc != 6) {
3960
printf("Both boot parameters must be specified\n");
4061
return 1;
4162
}
42-
if (PathFileExistsW(wargv[4]) && !PathIsDirectoryW(wargv[4])) {
43-
bootfilename = wargv[4];
63+
bootfilename = wargv[4];
4464
if (wcsicmp(wargv[5], L"Harddisk") == 0)
4565
emul = EmulationHardDisk;
4666
if (wcsicmp(wargv[5], L"288MFloppy") == 0)
@@ -49,72 +69,76 @@ int main(int argc, char ** argv) {
4969
emul = Emulation144MFloppy;
5070
if (wcsicmp(wargv[5], L"12MFloppy") == 0)
5171
emul = Emulation12MFloppy;
52-
isbootable = 1;
53-
}
72+
isbootable = 1;
5473
}
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...\nVolume name : %S\n", wargv[3]);
81+
hr = image->get_Root(&root);
82+
} else exit(1);
7583
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");
88105
}
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);
95110

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+
}
100116

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;
102120

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));
107126

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);
112132
}
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)\nFinished.\n", numBlocks, numDirs, numFiles);
138+
CloseHandle(hFile);
139+
116140
delete data;
117-
r_i->Release();
141+
isostream->Release();
118142
root->Release();
119143
result->Release();
120144
image->Release();

minbin/isoimage.exe

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)