diff -Nur orig/src/dos/dos.cpp new/src/dos/dos.cpp --- orig/src/dos/dos.cpp 2009-09-13 19:28:36.000000000 +0200 +++ new/src/dos/dos.cpp 2010-11-07 17:22:48.000000000 +0100 @@ -890,11 +890,25 @@ } break; } - case 0x5c: /* FLOCK File region locking */ + case 0x5c: /* FLOCK File region locking */ + /* ert, 20100711: Locking extensions */ + Bit32u pos=(reg_cx<<16) + reg_dx; + Bit32u size=(reg_si<<16) + reg_di; + //LOG_MSG("LockFile: BX=%d, AL=%d, POS=%d, size=%d", reg_bx, reg_al, pos, size); + if (DOS_LockFile(reg_bx,reg_al,pos, size)) { + reg_ax=0; + CALLBACK_SCF(false); + } else { + reg_ax=dos.errorcode; + CALLBACK_SCF(true); + } + break; + /* DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); reg_ax = dos.errorcode; CALLBACK_SCF(true); - break; + break; + */ case 0x5d: /* Network Functions */ if(reg_al == 0x06) { SegSet16(ds,DOS_SDA_SEG); diff -Nur orig/src/dos/dos_files.cpp new/src/dos/dos_files.cpp --- orig/src/dos/dos_files.cpp 2009-09-13 19:28:36.000000000 +0200 +++ new/src/dos/dos_files.cpp 2010-11-07 15:36:12.000000000 +0100 @@ -402,6 +402,20 @@ }; return Files[handle]->Seek(pos,type); } + +/* ert, 20100711: Locking extensions */ +bool DOS_LockFile(Bit16u entry,Bit8u mode,Bit32u pos,Bit32u size) { + Bit32u handle=RealHandle(entry); + if (handle>=DOS_FILES) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + if (!Files[handle] || !Files[handle]->IsOpen()) { + DOS_SetError(DOSERR_INVALID_HANDLE); + return false; + }; + return Files[handle]->LockFile(mode,pos,size); +} bool DOS_CloseFile(Bit16u entry) { Bit32u handle=RealHandle(entry); diff -Nur orig/src/dos/dos_misc.cpp new/src/dos/dos_misc.cpp --- orig/src/dos/dos_misc.cpp 2009-05-27 12:15:42.000000000 +0200 +++ new/src/dos/dos_misc.cpp 2010-11-07 22:12:48.000000000 +0100 @@ -58,7 +58,11 @@ } static bool DOS_MultiplexFunctions(void) { - switch (reg_ax) { + switch (reg_ax) { + /* ert, 20100711: Locking extensions */ + case 0x1000: /* SHARE.EXE installation check */ + reg_ax=0xffff; /* Pretend that share.exe is installed.. Of course it's a bloody LIE! */ + break; case 0x1216: /* GET ADDRESS OF SYSTEM FILE TABLE ENTRY */ // reg_bx is a system file table entry, should coincide with // the file handle so just use that diff -Nur orig/src/dos/drive_local.cpp new/src/dos/drive_local.cpp --- orig/src/dos/drive_local.cpp 2009-07-18 21:42:56.000000000 +0200 +++ new/src/dos/drive_local.cpp 2010-11-07 23:12:00.000000000 +0100 @@ -37,7 +37,8 @@ bool Read(Bit8u * data,Bit16u * size); bool Write(Bit8u * data,Bit16u * size); bool Seek(Bit32u * pos,Bit32u type); - bool Close(); + bool Close(); + bool LockFile(Bit8u mode, Bit32u pos, Bit16u size); Bit16u GetInformation(void); bool UpdateDateTimeFromHost(void); void FlagReadOnlyMedium(void); @@ -466,7 +467,50 @@ *size=(Bit16u)fwrite(data,1,*size,fhandle); return true; } -} +} + +/* ert, 20100711: Locking extensions */ +#ifdef WIN32 +#include +bool localFile::LockFile(Bit8u mode, Bit32u pos, Bit16u size) { + HANDLE hFile = (HANDLE)_get_osfhandle(_fileno(fhandle)); + BOOL bRet; + + switch (mode) + { + case 0: bRet = ::LockFile (hFile, pos, 0, size, 0); break; + case 1: bRet = ::UnlockFile(hFile, pos, 0, size, 0); break; + default: + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + return false; + } + //LOG_MSG("::LockFile %s", name); + + if (!bRet) + { + switch (GetLastError()) + { + case ERROR_ACCESS_DENIED: + case ERROR_LOCK_VIOLATION: + case ERROR_NETWORK_ACCESS_DENIED: + case ERROR_DRIVE_LOCKED: + case ERROR_SEEK_ON_DEVICE: + case ERROR_NOT_LOCKED: + case ERROR_LOCK_FAILED: + DOS_SetError(0x21); + break; + case ERROR_INVALID_HANDLE: + DOS_SetError(DOSERR_INVALID_HANDLE); + break; + case ERROR_INVALID_FUNCTION: + default: + DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID); + break; + } + } + return bRet; +} +#endif bool localFile::Seek(Bit32u * pos,Bit32u type) { int seektype; diff -Nur orig/include/dos_inc.h new/include/dos_inc.h --- orig/include/dos_inc.h 2009-09-13 19:28:32.000000000 +0200 +++ new/include/dos_inc.h 2010-11-07 15:03:22.000000000 +0100 @@ -112,7 +112,9 @@ void DOS_SetupFiles (void); bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount); bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount); -bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type); +bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type); +/* ert, 20100711: Locking extensions */ +bool DOS_LockFile(Bit16u entry,Bit8u mode,Bit32u pos,Bit32u size); bool DOS_CloseFile(Bit16u handle); bool DOS_FlushFile(Bit16u handle); bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); diff -Nur orig/include/dos_system.h new/include/dos_system.h --- orig/include/dos_system.h 2009-03-04 22:08:22.000000000 +0100 +++ new/include/dos_system.h 2010-11-07 15:12:12.000000000 +0100 @@ -70,7 +70,9 @@ virtual bool Read(Bit8u * data,Bit16u * size)=0; virtual bool Write(Bit8u * data,Bit16u * size)=0; virtual bool Seek(Bit32u * pos,Bit32u type)=0; - virtual bool Close()=0; + virtual bool Close()=0; + /* ert, 20100711: Locking extensions */ + virtual bool LockFile(Bit8u mode, Bit32u pos, Bit16u size) { return false; }; virtual Bit16u GetInformation(void)=0; virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); } virtual char* GetName(void) { return name; };