//=========================================================== // LCDOS - DOS stub for Launch Control // // Copyright (C) 1995 Ziff-Davis Publishing Company // First published in PC Magazine by Douglas Boling // // Revision History: // // 1.0 Initial Release // //=========================================================== #define dim(x) (sizeof(x) / sizeof(x[0])) #include #include #include #include #include #include // Include these because we are using some structures. #include "windows.h" #include "lc.h" char *GetEoN (char *); int PrintErrorString (char *); char *GetErrorString (int, char *); // Structure that holds program info MYPROGDATA Prog; char szFileTag[] = "LaunchCtl Data File 1.0 DMB\n"; char szPrompt[] = "\n\n\nPress any key to return to Windows\n"; // // Error messages // char *ErrStr[] = {"Could not open .LCD file", "Invalid LCD file format", "Could not read all of .LCD file", "Invalid function", "File not found", "Path not found", "Too many open files", "Access denied", "Invalid handle", "Arena Trashed", "Not enough memory", "Invalid Block", "Bad environment", "Bad format", "Invalid access", "Invalid data", "File open error 0E", "Invalid drive", "Current directory", "Not same device", "No more files", "Disk Write Protected", "Unknown unit", "Drive not ready", "Unknown command", "CRC Data Error", "Bad length", "Disk Seek error", "Not a DOS disk", "Sector not found", "Out of paper", "File Write fault", "File Read fault", "General failure", "File sharing violation"}; // // DOS entry point // int main (int argc, char *argv[]) { struct { WORD segEnv; LPSTR lpszCmdLine; LPSTR lpFCB1; LPSTR lpFCB2; } exec_struct; int i, sID = 0, rc = 0, p; BOOL fBat = FALSE; char szTail[128], *pszEnd; char szProgName[128]; FILE *handle; union REGS inregs, outregs; // Check to see if valid launch if (((argc < 2) || ((strcmp (argv[1], "/l") != 0)) && (strcmp (argv[1], "/w") != 0))) { printf ("This program requires Microsoft Windows\n"); return 1; } // See if WinGo present. If so, get ID off cmdline. if (strcmp (argv[1], "/w") == 0) { sID = atoi (argv[2]); p = 3; } else p = 2; // Open .LCD file handle = fopen (argv[p], "rb"); if (!handle) return PrintErrorString (GetErrorString (0, szTail)); // Read file tag to verify file i = fread (szTail, sizeof (char), sizeof (szFileTag), handle); if ((i != sizeof (szFileTag)) || strcmp (szTail, szFileTag)) rc = 1; else { // Read file data i = fread (&Prog, sizeof (char), sizeof (Prog), handle); if (i < sizeof (Prog)) rc = 2; } fclose (handle); if (rc) return PrintErrorString (GetErrorString (i, szTail)); // Make sure all of cmd line fit on line. If not, use internal cmd to // compute program name. if (strcmp (argv[p+2], "*") == 0) //Look for end of line tag strcpy (szProgName, argv[p+1]); else { // Fail gracefully by attempting to use the raw command. strcpy (szProgName, Prog.szCmd); pszEnd = GetEoN (szProgName); *pszEnd = '\0'; } // Set working directory if (strlen (Prog.szDir) != 0) { if (Prog.szDir[1] == ':') { //UCase drive letter & convert to num. _chdrive ((Prog.szDir[0] & 0xdf) - 0x40); } chdir (Prog.szDir); } // If BAT file, use shell prog to execute pszEnd = szProgName + strlen (szProgName); if (strcmpi (pszEnd-4, ".bat") == 0) { strcpy (&szTail[1], "/c "); strcat (&szTail[1], szProgName); strcpy (szProgName, getenv ("COMSPEC")); fBat = TRUE; } else szTail[1] = '\0'; // Find and copy command line tail pszEnd = GetEoN (Prog.szCmd); strcat (&szTail[1], pszEnd); // Tail must be length byte followed by tail terminated by CR szTail[0] = (char)strlen (&szTail[1]); pszEnd = &szTail[1] + (INT)szTail[0]; *pszEnd++ = 0x0d; *pszEnd = '\0'; exec_struct.segEnv = 0; exec_struct.lpszCmdLine = szTail; exec_struct.lpFCB1 = 0; exec_struct.lpFCB2 = 0; // DOS Exec inregs.x.ax = 0x4b00; inregs.x.bx = (WORD)&exec_struct; inregs.x.dx = (WORD)szProgName; intdos (&inregs, &outregs); if (outregs.x.cflag) { printf ("\n\nError executing command: "); printf (szProgName); printf (&szTail[1]); PrintErrorString (GetErrorString (rc+2, szTail)); } else if (!fBat) { // DOS get rc inregs.x.ax = 0x4d00; intdos (&inregs, &outregs); rc = outregs.x.ax; if (rc) { sprintf (szTail, "\nProgram returned error code: %x", rc); printf (szTail); printf (szPrompt); getchar (); } } // Reenable WinGo if necessary if (sID) { inregs.h.ah = (char)sID; inregs.h.al = 3; //Enable WinGo int86 (0x2f, &inregs, &outregs); } return i; } //------------------------------------------------------------ // GetEoN - returns a pointer to the end of a filename //------------------------------------------------------------ char *GetEoN (char *pszName) { char ch; while (*pszName) { ch = *pszName; if ((strchr (":\\.!#$%^&()-_{}~", ch) == 0) && !isalnum (*pszName)) break; pszName++; } return pszName; } //------------------------------------------------------------ // GetErrorString - Prints an error message and returns //------------------------------------------------------------ char *GetErrorString (int sErr, char *pszErr) { if (sErr < dim (ErrStr)) strcpy (pszErr, ErrStr[sErr]); else sprintf (pszErr, "Error number %x", sErr); return pszErr; } //------------------------------------------------------------ // PrintErrorString - Prints an error message and returns //------------------------------------------------------------ int PrintErrorString (char *szErr) { printf ("\n\n"); printf (szErr); printf (szPrompt); getchar (); return 2; }