Make mv's use signed chars explicitly.
[xiph/unicode.git] / oggds / main.cpp
bloba4a70d445c9b3cdcb95fae3fc648c2f09b6ed4da
1 /*******************************************************************************
2 * *
3 * This file is part of the Ogg Vorbis DirectShow filter collection *
4 * *
5 * Copyright (c) 2001, Tobias Waldvogel *
6 * All rights reserved. *
7 * *
8 * Redistribution and use in source and binary forms, with or without *
9 * modification, are permitted provided that the following conditions are met: *
10 * *
11 * - Redistributions of source code must retain the above copyright notice, *
12 * this list of conditions and the following disclaimer. *
13 * *
14 * - Redistributions in binary form must reproduce the above copyright notice, *
15 * this list of conditions and the following disclaimer in the documentation *
16 * and/or other materials provided with the distribution. *
17 * *
18 * - The names of the contributors may not be used to endorse or promote *
19 * products derived from this software without specific prior written *
20 * permission. *
21 * *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" *
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE *
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE *
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR *
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF *
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN *
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) *
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
32 * POSSIBILITY OF SUCH DAMAGE. *
33 * *
34 *******************************************************************************/
36 // This file contains the structures to register the filters and some
37 // additional code the register file types etc.
39 #include <streams.h> // DirectShow (includes windows.h)
40 #include "initguid.h"
41 #include "main.h"
42 #include "tchar.h"
43 #include <ShObjIdl.h>
44 #include "OggSplitterDS/OggSplitterDS.h"
45 #include "OggMuxDS/OggMuxDS.h"
46 #include "VorbEncDS/VorbEncDS.h"
47 #include "VorbDecDS/VorbDecDS.h"
48 #include "AboutPage.h"
49 #include "common.h"
51 const AMOVIESETUP_MEDIATYPE sudPCMAudio =
52 { &MEDIATYPE_Audio // clsMajorType
53 , &MEDIASUBTYPE_PCM }; // clsMinorType
55 const AMOVIESETUP_MEDIATYPE sudVorbis =
56 { &MEDIATYPE_Audio // clsMajorType
57 , &MEDIASUBTYPE_Vorbis }; // clsMinorType
59 const AMOVIESETUP_MEDIATYPE sudOggPackets =
60 { &MEDIATYPE_Audio // clsMajorType
61 , &MEDIASUBTYPE_Vorbis }; // clsMinorType
63 const AMOVIESETUP_MEDIATYPE sudOggStreams =
64 { &MEDIATYPE_Stream // clsMajorType
65 , &MEDIASUBTYPE_Ogg };
67 static const WCHAR sudOggSplitName[] = L"Ogg Splitter";
68 static const WCHAR sudOggMuxName[] = L"Ogg Multiplexer";
69 static const WCHAR sudVorbisEncName[] = L"Vorbis Encoder";
70 static const WCHAR sudVorbisDecName[] = L"Vorbis Decoder";
71 static const WCHAR sudOggDSAboutPageName[] = L"OggDS about page";
72 static const WCHAR sudOggMuxPropPageName[] = L"Ogg Multiplexer property page";
73 static const WCHAR sudOggSplitPropPageName[] = L"Ogg Splitter property page";
74 static const WCHAR sudVorbisEncPropPageName[] = L"Vorbis Compressor property page";
75 static const WCHAR sudVorbisDecPropPageName[] = L"Vorbis decoder property page";
77 #define OggFileDesc "Ogg Vorbis / Media File (*.ogg;*.ogm)"
78 #define OggFileDesc2 "Ogg Vorbis / Media File"
79 #define OggFileTypes "*.ogg;*.ogm"
80 #define OgmFileDesc "Ogg media file"
82 const AMOVIESETUP_PIN sudOggSplitPins[] =
83 { { L"Input" // strName
84 , FALSE // bRendered
85 , FALSE // bOutput
86 , FALSE // bZero
87 , FALSE // bMany
88 , &CLSID_NULL // clsConnectsToFilter
89 , L"" // strConnectsToPin
90 , 1 // nTypes
91 , &sudOggStreams // lpTypes
93 , { L"Output" // strName
94 , FALSE // bRendered
95 , TRUE // bOutput
96 , FALSE // bZero
97 , TRUE // bMany
98 , &CLSID_NULL // clsConnectsToFilter
99 , L"" // strConnectsToPin
100 , 0 // nTypes
101 , NULL // lpTypes
105 const AMOVIESETUP_FILTER sudOggSplit =
106 { &CLSID_OggSplitter // clsID
107 , sudOggSplitName // strName
108 , MERIT_NORMAL // dwMerit
109 , 2 // nPins
110 , sudOggSplitPins}; // lpPin
112 const AMOVIESETUP_PIN sudOggMuxPins[] =
113 { { L"Input" // strName
114 , FALSE // bRendered
115 , FALSE // bOutput
116 , FALSE // bZero
117 , TRUE // bMany
118 , &CLSID_NULL // clsConnectsToFilter
119 , L"" // strConnectsToPin
120 , 0 // nTypes
121 , NULL // lpTypes
123 , { L"Output" // strName
124 , FALSE // bRendered
125 , TRUE // bOutput
126 , FALSE // bZero
127 , FALSE // bMany
128 , &CLSID_NULL // clsConnectsToFilter
129 , L"" // strConnectsToPin
130 , 1 // nTypes
131 , &sudOggStreams // lpTypes
135 const AMOVIESETUP_FILTER sudOggMux =
136 { &CLSID_OggMux // clsID
137 , sudOggMuxName // strName
138 , MERIT_UNLIKELY // dwMerit
139 , 2 // nPins
140 , sudOggMuxPins}; // lpPin
142 const AMOVIESETUP_PIN sudVorbisEncPins[] =
144 { L"Input" // strName
145 , FALSE // bRendered
146 , FALSE // bOutput
147 , FALSE // bZero
148 , FALSE // bMany
149 , &CLSID_NULL // clsConnectsToFilter
150 , L"" // strConnectsToPin
151 , 1 // nTypes
152 , &sudPCMAudio // lpTypes
154 , { L"Output" // strName
155 , FALSE // bRendered
156 , TRUE // bOutput
157 , FALSE // bZero
158 , FALSE // bMany
159 , &CLSID_NULL // clsConnectsToFilter
160 , L"" // strConnectsToPin
161 , 1 // nTypes
162 , &sudVorbis // lpTypes
166 const AMOVIESETUP_FILTER sudVorbisEnc =
167 { &CLSID_VorbisEnc // clsID
168 , sudVorbisEncName // strName
169 , MERIT_DO_NOT_USE // dwMerit
170 , 2 // nPins
171 , sudVorbisEncPins};
173 const REGFILTER2 rf2FilterReg =
175 1, // Version 1 (no pin mediums or pin category).
176 MERIT_DO_NOT_USE, // Merit.
177 2, // Number of pins.
178 (AMOVIESETUP_PIN*)&sudVorbisEncPins // Pointer to pin information.
181 const AMOVIESETUP_PIN sudVorbisDecPins[] =
183 { L"Input" // strName
184 , FALSE // bRendered
185 , FALSE // bOutput
186 , FALSE // bZero
187 , FALSE // bMany
188 , &CLSID_NULL // clsConnectsToFilter
189 , L"" // strConnectsToPin
190 , 1 // nTypes
191 , &sudVorbis // lpTypes
193 , { L"Output" // strName
194 , FALSE // bRendered
195 , TRUE // bOutput
196 , FALSE // bZero
197 , FALSE // bMany
198 , &CLSID_NULL // clsConnectsToFilter
199 , L"" // strConnectsToPin
200 , 1 // nTypes
201 , &sudPCMAudio // lpTypes
205 const AMOVIESETUP_FILTER sudVorbisDec =
206 { &CLSID_VorbisDec // clsID
207 , sudVorbisDecName // strName
208 , MERIT_NORMAL // dwMerit
209 , 2 // nPins
210 , sudVorbisDecPins};
212 // Needed for the CreateInstance mechanism
213 CFactoryTemplate g_Templates[]=
214 { { sudOggSplitName
215 , &CLSID_OggSplitter
216 , COggSplitter::CreateInstance
217 , NULL
218 , &sudOggSplit
220 , { sudOggSplitPropPageName
221 , &CLSID_OggSplitPropPage
222 , COggSplitPropPage::CreateInstance
223 , NULL
224 , NULL
226 , { sudOggMuxName
227 , &CLSID_OggMux
228 , COggMux::CreateInstance
229 , NULL
230 , &sudOggMux
232 , { sudOggMuxPropPageName
233 , &CLSID_OggMuxPropPage
234 , COggMuxPropPage::CreateInstance
235 , NULL
236 , NULL
238 , { sudVorbisEncName
239 , &CLSID_VorbisEnc
240 , CVorbisEnc::CreateInstance
241 , NULL
242 , &sudVorbisEnc
244 , { sudVorbisEncPropPageName
245 , &CLSID_VorbisEncPropPage
246 , CVorbisEncPropPage::CreateInstance
247 , NULL
248 , NULL
250 , { sudVorbisDecName
251 , &CLSID_VorbisDec
252 , CVorbisDec::CreateInstance
253 , NULL
254 , &sudVorbisDec
256 , { sudVorbisDecPropPageName
257 , &CLSID_VorbisDecPropPage
258 , CVorbisDecPropPage::CreateInstance
259 , NULL
260 , NULL
262 , { sudOggDSAboutPageName
263 , &CLSID_OggDSAboutPage
264 , COggDSAboutPage::CreateInstance
265 , NULL
266 , NULL
269 int g_cTemplates = sizeof(g_Templates)/sizeof(g_Templates[0]);
272 STDAPI DllRegisterServer()
274 HRESULT hr;
276 if FAILED(hr = AMovieDllRegisterServer2(TRUE)) return hr;
278 // Register Vorbis Compresor as audio compressor
279 IFilterMapper2 *pFM2 = NULL;
281 if FAILED(hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
282 IID_IFilterMapper2, (void **)&pFM2)) return hr;
283 if FAILED(hr = pFM2->RegisterFilter(CLSID_VorbisEnc, sudVorbisEncName, NULL,
284 &CLSID_AudioCompressorCategory, sudVorbisEncName, &rf2FilterReg)) return hr;
285 pFM2->Release();
287 // Register Stream - Ogg filetype ...
288 // This will enable the File Source Filter to recognize that
289 // Ogg files contain media type Stream - Ogg
290 HKEY hkey = NULL;
291 LONG lreturn = ERROR_SUCCESS;
292 CHAR chMediaEntry[260];
293 CHAR chPattern[260];
294 CHAR chSourceFilter[CHARS_IN_GUID];
295 CHAR chMediaType[CHARS_IN_GUID];
296 CHAR chMediaSubtype[CHARS_IN_GUID];
298 OLECHAR szMediaType[CHARS_IN_GUID];
299 OLECHAR szMediaSubtype[CHARS_IN_GUID];
300 OLECHAR szAsyncReader[CHARS_IN_GUID];
301 OLECHAR szCLSID[CHARS_IN_GUID];
305 StringFromGUID2(MEDIATYPE_Stream, szMediaType, CHARS_IN_GUID);
306 StringFromGUID2(MEDIASUBTYPE_Ogg, szMediaSubtype, CHARS_IN_GUID);
307 StringFromGUID2(CLSID_AsyncReader, szAsyncReader, CHARS_IN_GUID);
308 wsprintf(chPattern, "0,4,,%x", ('O'<<24) + ('g'<<16) + ('g'<<8) + 'S');
309 wsprintf(chSourceFilter, "%ls", szAsyncReader);
310 wsprintf(chMediaType, "%ls", szMediaType);
311 wsprintf(chMediaSubtype, "%ls", szMediaSubtype);
313 // create the mediatype key
314 wsprintf(chMediaEntry, "Media Type\\%ls\\%ls", szMediaType, szMediaSubtype);
315 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, chMediaEntry, &hkey);
316 if (lreturn != ERROR_SUCCESS) continue;
318 // Tell the file source filter how to recognize Ogg Streams
319 // Ogg files start with "OggS" ...
320 lreturn = RegSetValueEx(hkey, "0", 0, REG_SZ, (CONST BYTE*)chPattern, strlen(chPattern));
321 if (lreturn != ERROR_SUCCESS) continue;
322 lreturn = RegSetValueEx(hkey, "Source Filter", 0, REG_SZ, (CONST BYTE*)chSourceFilter, strlen(chSourceFilter));
323 if (lreturn != ERROR_SUCCESS) continue;
324 RegCloseKey(hkey);
325 hkey = NULL;
327 // create the extension entry for ogg
328 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, "Media Type\\Extensions\\.ogg", &hkey);
329 if (lreturn != ERROR_SUCCESS) continue;
330 lreturn = RegSetValueEx(hkey, "Source Filter", 0, REG_SZ, (CONST BYTE*)chSourceFilter, strlen(chSourceFilter));
331 if (lreturn != ERROR_SUCCESS) continue;
332 lreturn = RegSetValueEx(hkey, "Media Type", 0, REG_SZ, (CONST BYTE*)chMediaType, strlen(chMediaType));
333 if (lreturn != ERROR_SUCCESS) continue;
334 lreturn = RegSetValueEx(hkey, "Subtype", 0, REG_SZ, (CONST BYTE*)chMediaSubtype, strlen(chMediaSubtype));
335 if (lreturn != ERROR_SUCCESS) continue;
336 RegCloseKey(hkey);
337 hkey = NULL;
339 // create the entry for .ogm
340 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, "Media Type\\Extensions\\.ogm", &hkey);
341 if (lreturn != ERROR_SUCCESS) continue;
342 lreturn = RegSetValueEx(hkey, "Source Filter", 0, REG_SZ, (CONST BYTE*)chSourceFilter, strlen(chSourceFilter));
343 if (lreturn != ERROR_SUCCESS) continue;
344 lreturn = RegSetValueEx(hkey, "Media Type", 0, REG_SZ, (CONST BYTE*)chMediaType, strlen(chSourceFilter));
345 if (lreturn != ERROR_SUCCESS) continue;
346 lreturn = RegSetValueEx(hkey, "Subtype", 0, REG_SZ, (CONST BYTE*)chMediaSubtype, strlen(chMediaSubtype));
347 if (lreturn != ERROR_SUCCESS) continue;
348 RegCloseKey(hkey);
349 hkey = NULL;
351 // The following registry entries enable the preview in the windows explorer
352 lreturn = RegCreateKey(HKEY_CLASSES_ROOT, ".ogm", &hkey);
353 if (lreturn != ERROR_SUCCESS) continue;
354 lreturn = RegSetValueEx(hkey, NULL, 0, REG_SZ, (CONST BYTE*)OgmFileDesc, strlen(OgmFileDesc));
355 if (lreturn != ERROR_SUCCESS) continue;
356 RegCloseKey(hkey);
357 hkey = NULL;
359 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, ".ogm\\ShellEx", &hkey);
360 if (lreturn != ERROR_SUCCESS) continue;
361 RegCloseKey(hkey);
362 hkey = NULL;
364 StringFromGUID2(IID_IExtractImage, szCLSID, CHARS_IN_GUID);
365 wsprintf(chMediaEntry, ".ogm\\ShellEx\\%S", szCLSID);
366 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, chMediaEntry, &hkey);
367 if (lreturn != ERROR_SUCCESS) continue;
368 StringFromGUID2(IID_IExtractImage, szCLSID, CHARS_IN_GUID);
369 wsprintf(chMediaEntry, "{c5a40261-cd64-4ccf-84cb-c394da41d590}");
370 lreturn = RegSetValueEx(hkey, NULL, 0, REG_SZ, (CONST BYTE*)chMediaEntry, strlen(chMediaEntry));
371 if (lreturn != ERROR_SUCCESS) continue;
372 RegCloseKey(hkey);
373 hkey = NULL;
375 // The following registry entries enable the preview in the windows explorer
376 lreturn = RegCreateKey(HKEY_CLASSES_ROOT, ".ogg", &hkey);
377 if (lreturn != ERROR_SUCCESS) continue;
378 lreturn = RegSetValueEx(hkey, NULL, 0, REG_SZ, (CONST BYTE*)OgmFileDesc, strlen(OgmFileDesc));
379 if (lreturn != ERROR_SUCCESS) continue;
380 RegCloseKey(hkey);
381 hkey = NULL;
383 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, ".ogg\\ShellEx", &hkey);
384 if (lreturn != ERROR_SUCCESS) continue;
385 RegCloseKey(hkey);
386 hkey = NULL;
388 StringFromGUID2(IID_IExtractImage, szCLSID, CHARS_IN_GUID);
389 wsprintf(chMediaEntry, ".ogg\\ShellEx\\%S", szCLSID);
390 lreturn = RegCreateKey( HKEY_CLASSES_ROOT, chMediaEntry, &hkey);
391 if (lreturn != ERROR_SUCCESS) continue;
392 StringFromGUID2(IID_IExtractImage, szCLSID, CHARS_IN_GUID);
393 wsprintf(chMediaEntry, "{c5a40261-cd64-4ccf-84cb-c394da41d590}");
394 lreturn = RegSetValueEx(hkey, NULL, 0, REG_SZ, (CONST BYTE*)chMediaEntry, strlen(chMediaEntry));
395 if (lreturn != ERROR_SUCCESS) continue;
396 RegCloseKey(hkey);
397 hkey = NULL;
399 // Register .ogg and .ogm for Media Player
400 lreturn = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\MediaPlayer\\Player\\Extensions\\Types", &hkey);
401 if (lreturn != ERROR_SUCCESS)
403 bool bOggAlreadyRegistered = false;
404 DWORD index = 0;
405 char pbName[256];
406 DWORD cbName = 256;
407 char pbValue[256];
408 DWORD cbValue = 256;
410 while(RegEnumValue(hkey, index, pbName, &cbName, NULL, NULL, (BYTE*)pbValue, &cbValue) == ERROR_SUCCESS)
412 pbValue[cbValue] = '\0';
413 pbName[cbValue] = '\0';
414 index++;
415 if (strstr(pbValue, ".ogg")) bOggAlreadyRegistered = true;
416 cbName = 256;
417 cbValue = 256;
420 if (!bOggAlreadyRegistered)
422 index = atoi(pbName);
423 index++;
424 wsprintf(pbName, "%d", index);
425 RegSetValueEx(hkey, pbName, 0, REG_SZ, (CONST BYTE*)OggFileTypes, strlen(OggFileTypes));
426 RegCloseKey(hkey);
427 RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\MediaPlayer\\Player\\Extensions\\Descriptions", &hkey);
428 RegSetValueEx(hkey, pbName, 0, REG_SZ, (CONST BYTE*)OggFileDesc, strlen(OggFileDesc));
429 RegCloseKey(hkey);
430 RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\MediaPlayer\\Player\\Extensions\\MUIDescriptions", &hkey);
431 RegSetValueEx(hkey, pbName, 0, REG_SZ, (CONST BYTE*)OggFileDesc2, strlen(OggFileDesc2));
433 RegCloseKey(hkey);
434 hkey = NULL;
437 // This for MediaPlayer 9
438 lreturn = RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Multimedia\\WMPlayer\\Extensions", &hkey);
439 if (lreturn == ERROR_SUCCESS)
441 HKEY hKeyNew ;
442 DWORD dwData = 7;
444 RegCreateKey(hkey, ".ogg", &hKeyNew);
445 RegSetValueEx(hKeyNew, "Runtime", 0, REG_DWORD, (BYTE*)&dwData, 4);
446 RegCloseKey(hKeyNew);
447 RegCreateKey(hkey, ".ogm", &hKeyNew);
448 RegSetValueEx(hKeyNew, "Runtime", 0, REG_DWORD, (BYTE*)&dwData, 4);
449 RegCloseKey(hKeyNew);
450 RegCloseKey(hkey);
451 hkey = NULL;
453 } while( 0 );
455 if (hkey)
456 RegCloseKey(hkey);
458 if (lreturn != ERROR_SUCCESS)
459 return AmHresultFromWin32(lreturn);
461 return NOERROR;
465 STDAPI DllUnregisterServer()
467 HRESULT hr;
469 if FAILED(hr = AMovieDllRegisterServer2(FALSE)) return hr;
471 // Deregister Vorbis Compressor as audio compressor
472 IFilterMapper2 *pFM2 = NULL;
474 if FAILED(hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
475 IID_IFilterMapper2, (void **)&pFM2)) return hr;
476 if FAILED(hr = pFM2->UnregisterFilter(&CLSID_AudioCompressorCategory,
477 sudVorbisEncName, CLSID_VorbisEnc)) return hr;
478 pFM2->Release();
480 // Remove registered file type ...
481 CHAR chMediaEntry[260];
482 OLECHAR szMediaType[CHARS_IN_GUID];
483 OLECHAR szMediaSubtype[CHARS_IN_GUID];
485 StringFromGUID2(MEDIATYPE_Stream, szMediaType, CHARS_IN_GUID);
486 StringFromGUID2(MEDIASUBTYPE_Ogg, szMediaSubtype, CHARS_IN_GUID);
487 wsprintf(chMediaEntry, "Media Type\\%ls\\%ls", szMediaType, szMediaSubtype);
488 EliminateSubKey(HKEY_CLASSES_ROOT, chMediaEntry);
489 EliminateSubKey(HKEY_CLASSES_ROOT, "Media Type\\Extensions\\.ogg");
490 EliminateSubKey(HKEY_CLASSES_ROOT, "Media Type\\Extensions\\.ogm");
491 EliminateSubKey(HKEY_CLASSES_ROOT, ".ogm");
492 return hr;
495 // Necessary to for static link to LIBCMT
496 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
498 extern BOOL WINAPI DllMain(
499 HANDLE hDllHandle,
500 DWORD dwReason,
501 LPVOID lpreserved
504 return DllEntryPoint((HINSTANCE)hDllHandle, dwReason, lpreserved);