source: trunk/mediafolder/c/createcd/createcd.c@ 108

Last change on this file since 108 was 108, checked in by gyoung, 23 months ago

Fix all the warnings and errors reported by CPPCheck.

File size: 13.4 KB
Line 
1/*
2 * This file is (C) Chris Wohlgemuth 1999-2005
3 */
4/*
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#define INCL_DOS
21#define INCL_DOSERRORS
22#define INCL_DOSDEVICES
23#define INCL_DOSDEVIOCTL
24#define INCL_DOSFILEMGR
25
26#include <os2.h>
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include "mediafolderinc.h"
31#include "mediafolderres.h"
32/* #include "sys_funcs.h" */
33
34#define LVM_IS_HARDDISK 0
35#define LVM_IS_PRM 1
36#define LVM_IS_CDROM 2
37#define LVM_IS_NETWORK 3
38#define LVM_IS_UNKNOWN 4
39
40/* Typedefs for LVM */
41typedef unsigned long CARDINAL32;
42typedef unsigned long DoubleWord; /* ULONG */
43typedef unsigned char BOOLEAN;
44
45#define VOLUME_NAME_SIZE 20
46#define FILESYSTEM_NAME_SIZE 20
47
48#ifdef ADDRESS
49 #undef ADDRESS
50#endif
51typedef void* ADDRESS;
52
53
54HMODULE hMod=NULLHANDLE;
55
56typedef struct _Volume_Control_Record {
57 DoubleWord Volume_Serial_Number;
58 ADDRESS Volume_Handle;
59 BOOLEAN Compatibility_Volume;
60 BYTE Device_Type;
61 BYTE Reserved[2]; /* Padding */
62} Volume_Control_Record;
63
64typedef struct _Volume_Control_Array {
65 Volume_Control_Record* Volume_Control_Data;
66 CARDINAL32 Count;
67} Volume_Control_Array;
68
69typedef struct _Volume_Information_Record {
70 CARDINAL32 Volume_Size;
71 CARDINAL32 Partition_Count;
72 CARDINAL32 Drive_Letter_Conflict;
73 BOOLEAN Compatibility_Volume;
74 BOOLEAN Bootable;
75 char Drive_Letter_Preference;
76 char Current_Drive_Letter;
77 char Initial_Drive_Letter;
78 BOOLEAN New_Volume;
79 BYTE Status;
80 BYTE Reserved_1; /* PAdding */
81 char Volume_Name[VOLUME_NAME_SIZE];
82 char File_System_Name[FILESYSTEM_NAME_SIZE];
83} Volume_Information_Record;
84
85typedef Volume_Control_Array (_System _PFNVCA) ();
86typedef _PFNVCA *PFNVCA;
87
88typedef Volume_Information_Record (_System _PFNVIR) ();
89typedef _PFNVIR *PFNVIR;
90
91PFN pfnOpen_LVM_Engine=NULLHANDLE;
92PFN pfnClose_LVM_Engine=NULLHANDLE;
93PFNVCA pfnvcaGet_Volume_Control_Data=NULLHANDLE;
94PFNVIR pfnvirGet_Volume_Information=NULLHANDLE;
95
96size_t strlcpy(char *dst, const char *src, size_t siz);
97
98/*
99 FIXME:
100
101 Use the function from the \common_funcs directory instead.
102 */
103static BOOL getMessage(char* text,ULONG ulID, LONG lSizeText, HMODULE hResource)
104{
105 char* pOffset = 0;
106 char* ptr = 0;
107 int id=0;
108
109 text[0]='\0';
110
111 // printf("resource: %x, %d %d\n", hResource, ulID, (ulID/16)+1,
112 // DosGetResource(hResource, RT_STRING, (ulID/16)+1, (PVOID)&pOffset));
113
114 if(DosGetResource(hResource, RT_STRING, (ulID/16)+1, (PVOID)&pOffset)!=NO_ERROR)
115 return FALSE;
116
117 ptr=pOffset;
118
119 //printf("\ngot resource...\n");
120
121 /* Parsing... */
122 id=ulID%16;
123
124 //printf("id: %d\n", id);
125 pOffset+=sizeof(USHORT); /* Skip codepage */
126
127 for(;id > 0;id--)
128 {
129 //printf("id: %d, length: %d %s\n", id, *pOffset, pOffset+1);
130 pOffset+=*pOffset+1;
131 }
132 //printf("length: %d %s\n", *pOffset, pOffset+1);
133 strlcpy(text, pOffset+1, lSizeText);
134
135 if(*pOffset!=1){
136 DosFreeResource(ptr);
137 return TRUE;
138 }
139 DosFreeResource(ptr);
140/* Length=1 means dummy entry filled by system */
141 return FALSE;
142}
143
144#if 0
145#pragma import(DosQueryModFromEIP,,"DOSCALL1",360)
146 APIRET APIENTRY DosQueryModFromEIP ( HMODULE *phMod, ULONG *pObjNum, ULONG BuffLen, PCHAR pBuff, ULONG *pOffset, PVOID Address ) ;
147#endif
148
149/* This function returns the module handle of our ressource dll */
150static HMODULE queryResModuleHandle(void)
151{
152 char path[CCHMAXPATH];
153 char buf[CCHMAXPATH];
154 char* found;
155 APIRET rc;
156 HMODULE RESSOURCEHANDLE;
157 HMODULE hmod;
158 PTIB ptib = NULL;
159 PPIB ppib = NULL;
160
161
162 // printf("rc=%d\n",DosQueryModFromEIP( &hmod, &ul, sizeof(path), path,
163 // &off, (PVOID)queryResModuleHandle ) );
164 if(NO_ERROR==DosGetInfoBlocks(&ptib, &ppib))
165 DosQueryModuleName (ppib->pib_hmte, /* Module handle to query */
166 sizeof(path), /* Maximum length of result */
167 path);
168
169 //printf("%s %x\n",path, hmod);
170
171 /* Get the language code of our system and load the
172 resource DLL with the right language */
173 do
174 {
175 static char chrLang[]="en_EN";
176 PSZ pszLang="";
177 char *chrPtr;
178
179 /* Get Language var */
180 if(NO_ERROR!=DosScanEnv("LANG", &pszLang)) {
181 pszLang=chrLang;
182 }
183 /* Skip leading spaces */
184 chrPtr=pszLang;
185 while(*chrPtr==' ')
186 chrPtr++;
187
188 /* Check if value seems to be valid. The var must be something like xx_XX thus length is 5 */
189 if(strlen(chrPtr)<5)
190 break;
191
192 if((found=strrchr(path, '\\'))!=NULLHANDLE)
193 *found=0;
194
195 /* Extract the first two chars and build DLL name */
196 sprintf(buf, RESDLLNAME, chrPtr[0], chrPtr[1]);
197 strcat(path,buf);
198
199 rc=DosLoadModule(buf,sizeof(buf),path, &RESSOURCEHANDLE);
200 if(rc==NO_ERROR)
201 break;
202
203 /* NLS DLL not found. Try to load default */
204 found=strrchr(path,'\\');
205 if(!found)
206 break;
207
208 *found=0;
209 sprintf(buf, DEFRESDLLNAME);
210 strcat(path,buf);
211
212 rc=DosLoadModule(buf,sizeof(buf),path, &RESSOURCEHANDLE);
213 if(rc!=NO_ERROR) {
214 RESSOURCEHANDLE=NULLHANDLE;
215 }
216 else {
217 // printf("Ressource DLL loaded.\n");
218 }
219 break;
220 }while(TRUE);
221
222 return RESSOURCEHANDLE;
223}
224
225
226static BOOL loadLVMFuncs(void)
227{
228 char chrErrorObject[CCHMAXPATH]={0};
229 ULONG ulCB;
230
231 /* Try to load LVM */
232 if(DosLoadModule(chrErrorObject, sizeof(chrErrorObject), "LVM.DLL", &hMod)!=NO_ERROR)
233 return FALSE;
234 // printf("Got LVM.DLL\n");
235
236 for(;;) {
237 /* Get proc addresses */
238 if(DosQueryProcAddr(hMod, 0, "Open_LVM_Engine", &pfnOpen_LVM_Engine)!=NO_ERROR)
239 break;
240 // printf("Got Open_LVM_Engine: %x\n", pfnOpen_LVM_Engine);
241
242 if(DosQueryProcAddr(hMod, 0, "Close_LVM_Engine", &pfnClose_LVM_Engine)!=NO_ERROR)
243 break;
244 // printf("Got Close_LVM_Engine\n");
245
246 if(DosQueryProcAddr(hMod, 0, "Get_Volume_Control_Data", (PFN*)&pfnvcaGet_Volume_Control_Data)!=NO_ERROR)
247 break;
248 // printf("Got Get_Volume_Control_Data: %x\n", pfnvcaGet_Volume_Control_Data);
249
250 if(DosQueryProcAddr(hMod, 0, "Get_Volume_Information", (PFN*)&pfnvirGet_Volume_Information)!=NO_ERROR)
251 break;
252 // printf("Got Get_Volume_Information: %x\n", pfnvirGet_Volume_Information);
253
254 return TRUE;
255 }
256 DosFreeModule(hMod);
257 return FALSE;
258}
259
260/**************************************************************/
261/* */
262/* This funktion returns the CD-Drives in the system */
263/* */
264/* iNumCD (output): # of CD-Drives */
265/* cFirstDrive (output): first cd-Drive letter */
266/* returns TRUE: We have cd-drives */
267/* */
268/**************************************************************/
269BOOL CDQueryCDDrives(int *iNumCD, char * cFirstDrive)
270{
271 HFILE hfDevice;
272 ULONG ulAction;
273 ULONG ulLen;
274 static char cFirst=0;
275 static int iNumCDLocal=0;
276 static BOOL haveCD=FALSE;
277 static BOOL done=FALSE;
278 struct
279 {
280 USHORT usCountCD;
281 USHORT usFirstCD;
282 } CDInfo;
283
284 if(!done){
285 ulLen = sizeof(CDInfo);
286 if(!DosOpen("\\DEV\\CD-ROM2$", &hfDevice, &ulAction, 0,
287 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
288 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL))
289 {
290 if(!DosDevIOCtl(hfDevice, 0x82, 0x60, NULL, 0, NULL, &CDInfo, ulLen, &ulLen))
291 {
292 if(CDInfo.usCountCD) {
293 haveCD=TRUE;
294 iNumCDLocal=CDInfo.usCountCD;
295 cFirst='A'+ CDInfo.usFirstCD;
296 }
297 }
298 DosClose(hfDevice);
299 }
300 done=TRUE;
301 }
302 *iNumCD=iNumCDLocal;
303 *cFirstDrive=cFirst;
304 return haveCD;
305}
306
307int main(int argc, char** argv)
308{
309 CARDINAL32 error;
310 int iNumCD;
311 char cFirst;
312 char setup[512];
313 char name[256];
314 char id[100];
315 char nameTemplate[256];
316 int a;
317 HMODULE hmodRes=NULLHANDLE;
318
319 if(!CDQueryCDDrives(&iNumCD, &cFirst))
320 exit(1);
321
322 hmodRes=queryResModuleHandle();
323
324 if(!getMessage(nameTemplate, /* IDSTR_LAUNCHPADFLYOVER */ IDSTR_CDFOLDERNAME, sizeof(nameTemplate), hmodRes))
325 strncpy(nameTemplate, "CD-Audio player^Drive %c:", sizeof(nameTemplate));
326
327 if(!loadLVMFuncs()) {
328 for(a=0;a<iNumCD;a++) {
329 int b;
330 /* Build folder name */
331 sprintf(name, nameTemplate, cFirst+a);
332 /* Build object ID */
333 sprintf(id, CDFLDR_ID, cFirst+a);
334 /* Build setup string */
335 sprintf(setup, "%s=%c:;OBJECTID=%s;", CDFLDR_DRIVE, cFirst+a, id);
336 // DosSleep(1500);
337 for(b=1;b<=5;b++) {
338 /* Wait to let WPS load the class if not yet done. Then retry */
339 if(WinCreateObject(CDFLDR_CLASSNAME, name, setup,CDFLDR_LOCATION, CO_UPDATEIFEXISTS))
340 /*printf("Can't create %s\n", name);*/
341 break;
342 DosSleep(5000);
343 }
344 }
345 }
346 else {
347 /* LVM system */
348 printf("This is a LVM system\n");
349
350 pfnOpen_LVM_Engine(TRUE, &error);
351 if(!error) {
352 Volume_Control_Array vca={0};
353 printf("LVM engine opened\n");
354
355 vca= pfnvcaGet_Volume_Control_Data(&error);
356 if(!error) {
357 int a;
358
359 printf("Successfully got volume data\n");
360 for(a=0; a<vca.Count; a++) {
361 /* Now check all device types */
362 if(vca.Volume_Control_Data[a].Device_Type==LVM_IS_CDROM) {
363 Volume_Information_Record vir;
364 int b;
365
366 vir=pfnvirGet_Volume_Information(vca.Volume_Control_Data[a].Volume_Handle, &error);
367 if(!error) {
368 //printf("Device_type: %d, drive letter: %c:\n",
369 // vca.Volume_Control_Data[a].Device_Type, vir.Current_Drive_Letter);
370
371 /* Build folder name */
372 sprintf(name, nameTemplate, vir.Current_Drive_Letter);
373 /* Build object ID */
374 sprintf(id, CDFLDR_ID, vir.Current_Drive_Letter);
375 /* Build setup string */
376 sprintf(setup, "%s=%c:;OBJECTID=%s;", CDFLDR_DRIVE, vir.Current_Drive_Letter, id);
377
378 for(b=1;b<=5;b++) {
379 /* Wait to let WPS load the class if not yet done. Then retry */
380
381 if(WinCreateObject(CDFLDR_CLASSNAME, name, setup, CDFLDR_LOCATION, CO_UPDATEIFEXISTS))
382 break;
383 // printf("Found: %s, %s\n", name, setup);
384 DosSleep(5000);
385 } /* for(b)*/
386 }
387 }
388 }/* for(a) */
389 }
390 /* Close engine */
391 pfnClose_LVM_Engine();
392 }
393 DosFreeModule(hMod);
394 } /* else */
395 if(hmodRes)
396 DosFreeModule(hmodRes);
397 return (0);
398}
399
400
401/********************************************************************/
402/* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
403
404/*
405 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
406 *
407 * Permission to use, copy, modify, and distribute this software for any
408 * purpose with or without fee is hereby granted, provided that the above
409 * copyright notice and this permission notice appear in all copies.
410 *
411 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
412 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
413 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
414 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
415 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
416 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
417 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
418 */
419
420
421/*
422 * Copy src to string dst of size siz. At most siz-1 characters
423 * will be copied. Always NUL terminates (unless siz == 0).
424 * Returns strlen(src); if retval >= siz, truncation occurred.
425 */
426static size_t
427strlcpy(char *dst, const char *src, size_t siz)
428{
429 register char *d = dst;
430 register const char *s = src;
431 register size_t n = siz;
432
433 /* Copy as many bytes as will fit */
434 if (n != 0 && --n != 0) {
435 do {
436 if ((*d++ = *s++) == 0)
437 break;
438 } while (--n != 0);
439 }
440
441 /* Not enough room in dst, add NUL and traverse rest of src */
442 if (n == 0) {
443 if (siz != 0)
444 *d = '\0'; /* NUL-terminate dst */
445 while (*s++)
446 ;
447 }
448
449 return(s - src - 1); /* count does not include NUL */
450}
451
Note: See TracBrowser for help on using the repository browser.