⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel.cpp

📁 DVD工具dvdsynth的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 Copyright 2002 Ben Rudiak-Gould.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
 or visit <http://www.gnu.org/copyleft/gpl.html>.
***********************************************************************/


// Under Win2K the DVDSynth "kernel" runs in user mode. It duplicates some
// of the functionality of the Win95 kernel-mode code.


#include "kernel.h"
#include "miniport.h"
#include "asm.h"
#include "../dvdproxy2k/dvdproxy2k.h"
#include "../include/dvdsynth-device.h"

#include <stdio.h>

#include <process.h>


namespace KernelThread {
   void AsyncDispatch(unsigned char* buffer, scsi_result_t* result_storage, HANDLE event_done);
}


extern DvsBasePluginCallbacks* g_callbacks;  // in VDevice.cpp
void AsyncUserModeCall(void (*f)(void*, int), void* p, int i);  // in VDevice.cpp


/*******************************************************************\
\*******************************************************************/


class Semaphore {
   HANDLE s;
public:
   Semaphore() {
      s = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
   }
   void P() {
      WaitForSingleObject(s, INFINITE);
   }
   bool TimedP(unsigned timeout) {
      return WaitForSingleObject(s, timeout) == WAIT_OBJECT_0;
   }
   void V() {
      ReleaseSemaphore(s, 1, NULL);
   }
};

class CriticalSection {
   CRITICAL_SECTION cs;
public:
   CriticalSection() { InitializeCriticalSection(&cs); }
   ~CriticalSection() { DeleteCriticalSection(&cs); }
   void Acquire() { EnterCriticalSection(&cs); }
   void Release() { LeaveCriticalSection(&cs); }
};

// clobbers "next" pointer in Msg class
template<class Msg>
class MessageQueue {
   CriticalSection mutex;
   Semaphore slots_used;
   Msg* head;
   Msg** tail;
public:
   MessageQueue() {
      head = 0;
      tail = &head;
   }

   void Put(Msg* msg) {
      mutex.Acquire();
      *tail = msg;
      tail = &msg->next;
      *tail = 0;
      mutex.Release();
      slots_used.V();
   }

   Msg* Get() {
      slots_used.P();
      mutex.Acquire();
      Msg* result = head;
      if (result) {
         head = result->next;
         if (head == 0) {
            tail = &head;
         }
      }
      mutex.Release();
      return result;
   }
};


/*******************************************************************\
\*******************************************************************/

#ifdef __GNUC__

#define ASM		__asm__ (
#define ENDASM		);
#define L(l)		#l ":\n"

#define EAX		"%eax"
#define EBX		"%ebx"
#define ECX		"%ecx"
#define EDX		"%edx"
#define ESI		"%esi"
#define EDI		"%edi"
#define EBP		"%ebp"
#define ESP		"%esp"

#define RI(r,i)		#i "(" r ")"
#define RR(r1,r2)	"(" r1 "," r2 ")"
#define RRI(r1,r2,i)	#i "(" r1 "," r2 ")"
#define RRS(r1,r2,s)	"(" r1 "," r2 "," #s ")"
#define RRSI(r1,r2,s,i)	#i "(" r1 "," r2 "," #s ")"

#define PUSH(r)		"\tpush\t"	r		"\n"
#define POP(r)		"\tpop\t"	r		"\n"
#define RET		"\tret\n"
#define RETP(n)		"\tretn\t"	#n		"\n"
#define MOV(d,s)	"\tmovl\t"	s "," d		"\n"
#define DEC(r)		"\tdecl\t"	r		"\n"
#define SHR(r,n)	"\tshrl\t"	r "," #n	"\n"
#define JZ(l)		"\tjz\t"	#l		"\n"
#define JNZ(l)		"\tjnz\t"	#l		"\n"
#define CALL(a)		"\tcall\t"	a		"\n"
#if 0
__declspec(naked)
void* __cdecl MakeThunkCall(void* func, void* args, unsigned arg_bytes) {
ASM

PUSH(EBP)
MOV(EBP,ESP)

MOV(EDX,RI(EBP,12))    /* args */
MOV(ECX,RI(EBP,16))    /* arg_bytes */
SHR(ECX,2)
JZ(make_call)

L(copy_loop)
DEC(ECX)
PUSH(RRS(EDX,ECX,4))
JNZ(copy_loop)

L(make_call)
CALL(RI(EBP,8))        /* func */

MOV(ESP,EBP)
POP(EBP)
RET

ENDASM
}
#endif
#else

__declspec(naked)
void* __cdecl MakeThunkCall(void* func, void* args, unsigned arg_bytes) {
   __asm {
      push  ebp
      mov   ebp,esp

      mov   edx,[ebp+12]   /* args */
      mov   ecx,[ebp+16]   /* arg_bytes */
      shr   ecx,2
      jz    make_call

copy_loop:
      dec   ecx
      push  [edx+ecx*4]
      jnz   copy_loop

make_call:
      call  [ebp+8]        /* func */

      mov   esp,ebp
      pop   ebp
      ret
   }
}

#endif


/*******************************************************************\
\*******************************************************************/


namespace KernelThread {

   DvsDeviceKernel* handler[num_bays];

   struct KernelRequest {
      enum { dispatch, setHandler, callInitFunc, driverCall, quit } type;
      union {
         struct {
            unsigned char* buffer;
            scsi_result_t* result_storage;
            HANDLE event_done;
         } dispatch_args;
         struct {
            int target;
            DvsDeviceKernel* kernel_handler;
         } setHandler_args;
         struct {
            HMODULE hmodule;
         } callInitFunc_args;
         struct {
            void* func;
            void* args;
            int arg_bytes;
            void** return_value;
            HANDLE return_notify;
         } driverCall_args;
      };
      KernelRequest* next;
   };

   MessageQueue<KernelRequest> request_queue;

   void MemSet(void* dst, int val, unsigned long count) {
      memset(dst, val, count);
   }
   void MemCpy(void* dst, const void* src, unsigned long count) {
      memcpy(dst, src, count);
   }

   void DebugPrintf(const char* fmt, ...) {
      OutputDebugString("DvsDockingBayKernelGlobal::DebugPrintf\n");
   }

   int ReadFile(dvs_file_handle file_handle, unsigned offset, unsigned offset_high, unsigned count, void* buf) {
      HANDLE h = HANDLE(file_handle);
      LONG oh = offset_high;
      ::SetFilePointer(h, offset, &oh, FILE_BEGIN);
      DWORD read = count;
      if (::ReadFile(h, buf, count, &read, NULL))
         return read;
      else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -