Exemple #1
0
    std::int64_t getDiskSpaceInfo (const String& path, const bool total)
    {
        ULARGE_INTEGER spc, tot, totFree;

        if (GetDiskFreeSpaceEx (getDriveFromPath (path).toWideCharPointer(), &spc, &tot, &totFree))
            return total ? (std::int64_t) tot.QuadPart
                         : (std::int64_t) spc.QuadPart;

        return 0;
    }
 unsigned int getWindowsDriveType (const String& path)
 {
     return GetDriveType (getDriveFromPath (path).toWideCharPointer());
 }
Exemple #3
0
// ------------------------------------------------------------------
// LONG Pexec( mode, fname, cmdline, envstr )
int32_t custom_pexec( void *sp )
{
	BYTE *params = (BYTE *) sp;

	// retrieve params from stack
	mode    = *((WORD *) params);
	params += 2;
	fname	= (char *)	*((DWORD *) params);
	params += 4;
	cmdline	= (char *)	*((DWORD *) params);
	params += 4;
	envstr	= (char *)	*((DWORD *) params);

	// for any other than these modes don't do anything special, just call the original
	if(mode != PE_LOADGO && mode != PE_LOAD) {                              // not one of 2 supported modes? Call original Pexec()
        pexec_callOrig = 1;                                                 // will call the original Pexec() handler from asm when this finishes
        return 0;
	}

	// if we got here, the mode is PE_LOADGO || PE_LOAD
	WORD drive = getDriveFromPath((char *) fname);

	if(!isOurDrive(drive, 0)) {												// not our drive? Call original Pexec()
        pexec_callOrig = 1;                                                 // will call the original Pexec() handler from asm when this finishes
        return 0;
	}

    // Do PE_LOAD, and if this was PE_LOADGO, then the GO part will be done in gemdos_asm.s

	// if we got here, then it's a PRG on our drive...

	BYTE prgStart[32];

	pPrgStart = &prgStart[4];
	pPrgStart = (BYTE *) (((DWORD) pPrgStart) & 0xfffffffc);				// make temp buffer pointer to be at multiple of 4

	// create base page
    BYTE *pBasePage = (BYTE *) Pexec(PE_BASEPAGE, 0, cmdline, envstr);

	if((int) pBasePage < 1000) {											// Pexec seems to failed -- insufficient memory
		return ENSMEM;
	}

	TBasePage *sBasePage = (TBasePage *) pBasePage;							// this is now the pointer to the basePage structure

	// load the file to memory
	int32_t file = Fopen(fname, 0);											// try to open the file
	if(file < 0) {															// if the handle is negative, fail -- file not found
		freeTheBasePage(sBasePage);											// free the base page
		return EFILNF;
	}

	DWORD diskProgSize = Fseek(0, file, 2);									// seek to end, returns file size (bytes before end)
	Fseek(0, file, 0);														// seek to the start

	if(diskProgSize < 28) {													// if the program is too small, this wouldn't work
		Fclose(file);														// close the file
		freeTheBasePage(sBasePage);											// free the base page
		return EPLFMT;														// be Invalid program load format
	}

	Fread(file, 28, pPrgStart);												// read first 28 bytes to this buffer
	TPrgHead *prgHead = (TPrgHead  *) pPrgStart;

	// get file size, see if it will fit in the free memory
	DWORD memProgSize		= prgHead->tsize + prgHead->dsize + prgHead->bsize + prgHead->ssize;	// calculate the program size in RAM as size of text + data + bss + symbols
	DWORD memoryAvailable	= sBasePage->hitpa - sBasePage->lowtpa;									// calculate how much memory we have for the program

	if(memoryAvailable < memProgSize || memoryAvailable < diskProgSize) {	// if the program (in RAM or on disk) is bigger than the available free memory
		Fclose(file);														// close the file
		freeTheBasePage(sBasePage);											// free the base page
		return ENSMEM;														// error: insufficient memory
	}

	Fread(file, diskProgSize - 28, pBasePage + 0x100);						// now read the rest of the file
	Fclose(file);

	// fill the base page
	sBasePage->tbase	= sBasePage->lowtpa + 0x100;
	sBasePage->tlen		= prgHead->tsize;
	sBasePage->dbase	= sBasePage->tbase + sBasePage->tlen;
	sBasePage->dlen		= prgHead->dsize;
	sBasePage->bbase	= sBasePage->dbase + sBasePage->dlen;
	sBasePage->blen		= prgHead->bsize;

	// do the addresses fixup if needed
	BYTE *fixups		= (BYTE *) (sBasePage->tbase + prgHead->tsize + prgHead->dsize + prgHead->ssize);
	DWORD fixupOffset	= *((DWORD *) fixups);

    BYTE fixup = 0;

	if(fixupOffset != 0) {						                    // if fixup needed?
		BYTE *pWhereToFix;

		pWhereToFix	= (BYTE *) (sBasePage->tbase + fixupOffset);	// calculate the first DWORD position that needs to be fixed
		fixups += 4;												// move to the fixups array

		while(1) {
			DWORD oldVal = *((DWORD *)pWhereToFix);
			DWORD newVal = oldVal + sBasePage->tbase;

            if(fixup != 1) {                                        // fix the value only if the fixup isn't ONE
                *((DWORD *)pWhereToFix) = newVal;
            }

			fixup = *fixups;
			fixups++;

			if(fixup == 0) {                                        // terminate fixup
				break;
			}

			if(fixup == 1) {                                        // just move forward by 0xfe
				pWhereToFix += 0xfe;
			} else {                                                // move forward and fixup
                pWhereToFix += (DWORD) fixup;
            }
		}
	}

	memset((BYTE *) sBasePage->bbase, 0, sBasePage->blen);			// clear BSS section

    if(mode == PE_LOADGO) {                                         // if we're doing PE_LOADGO, then we're going to freeTheBasePage()
        pLastBasePage = pBasePage;
		pexec_postProc = 1;											// mark that after this function ends, the asm handler should do PE_GO part...
    }

    // Return the pointer to basepage.
    // for PE_LOAD this will be used as return value.
    // for PE_LOADGO this will be used to call Pexec(PE_GO) in gemdos_asm.s after this custom function.
	return (DWORD) pBasePage;										// the PE_LOAD was successful
}