Analysis of SoftRAM 95 SOFTRAM2.386
-----------------------------------

Introduction:

SOFTRAM2.386 is one of two virtual device drivers (VxDs) used by
Synchronys Softcorp's SoftRAM 95 when installed for Windows 3.1.
This analysis of the code in SOFTRAM2.386 was posted anonymously.  I
did *not* write it. However, I have briefly looked at a disassembly
listing for SOFTRAM2.386, and compared it with the PAGESWAP.ASM
sample code that Microsoft ships with the Windows 3.1 Device Driver
Kit (DDK), and have confirmed that large parts of the SOFTRAM2.386
code are absolutely identical to the copyrighted Microsoft code. 

The DDK license agreement does permit redistribution of the sample
code (such as PAGESWAP.ASM) in object-code form, but "only in
conjunction with and as part of your software product which adds
primary and significant functionality to the redistributable
components."  It is obvious from the following analysis that 
SOFTRAM2.386 does not add significant functionality to Microsoft's
PAGESWAP.ASM.

                                    -- Andrew Schulman

;----------------------------------------------------------------------

Softram2.386 is virtually identical to pageswap.386 from the Windows 3.1 DDK.

Unchanged functions:
   PageSwap_Control              PageSwap_System_Exit
   PageSwap_Test_Create          PageSwap_Create
   PageSwap_Destroy              PageSwap_Free_Page_Range
   PageSwap_In                   PageSwap_Out
   PageSwap_Find_Free_Page       PageSwap_Test_Page_Present
   PageSwap_Test_IO_Valid        PageSwap_Idle
   PageSwap_Test_Dirty_Count     PageSwap_Grow_File
   PageSwap_Read_Or_Write        PageSwap_Read_Now
   PageSwap_Read_Ahead           PageSwap_Write
   PageSwap_Ensure_Command_Done  PageSwap_Callback
   PageSwap_Flush_Writes         PageSwap_Find_Buffer
   PageSwap_Unlink_CB            PageSwap_Link_CB
   PageSwap_Find_Page            PageSwap_Debug_Query
   PageSwap_Sys_Critical_Init


Changed functions:

PageSwap_Get_Version:

   Changed to insert this code towards the end of it (which changes the 
   reported version)

      mov ecx, [PS_Max_File_Pages]     ; line 766 in  pageswap.asm
      mov eax, [Ini_SoftRam]
      or eax, eax
      jz PS_GV_No_SoftRam
      cmp bl, 3
      jne PS_GV_No_SoftRam
      movzx eax, [PS_Num_Buffers]
      or eax, eax
      jnz PS_GV_No_SoftRam
      mov eax, [Ini_SoftRamSize]
      shr eax, 2
      add ecx, eax

   PS_GV_No_SoftRam:
      mov     eax,0C03h
      clc                              ; line 768
      ret

PageSwap_Immediate_IO:

   This function was changed, somewhat strangely.  I'm just going to copy 
   the disassembled listings here, and then comment on them.

   PageSwap_Immediate_IO proc near
      VMMcall Log_Proc_Call
      pusha
      mov ebx,2BBCh
      mov dword ptr [ebx+14h],1B9Ch
      mov byte ptr [ebx+6],ch
      mov byte ptr [ebx+7],1
      mov dword ptr [ebx+8],edx
      mov dword ptr [ebx+0Ch],esi
      mov dword ptr [ebx+10h],edi
      jmp short PS_Jump_Around_Bogus_Code
                                 ;* No entry point to code
      nop
      nop
      nop
      mov eax,Ini_SoftRam
      or  eax,eax
      jz  PS_Jump_Around_Bogus_Code
      mov eax,Unknown_SRAM_Var_3 
      or  eax,eax
      jz  PS_Jump_Around_Bogus_Code
      mov eax,0
      mov al,ch
      mov ah,0
      mov esi,dword ptr [ebx+10h]
      mov edi,dword ptr [ebx+0Ch]
      mov ecx,dword ptr Unknown_SRAM_Var_3
      mov ebx,dword ptr Unknown_SRAM_Var_2
      cmp eax,2
      je  loc_60

   PS_Jump_Around_Bogus_Code:
      mov ebx,2BBCh
      mov ch,byte ptr [ebx+6]
      mov edx,dword ptr [ebx+8]
      mov esi,dword ptr [ebx+0Ch]
      mov edi,dword ptr [ebx+10h]
      VxDcall PageFile_Read_Or_Write
      mov eax,PS_Immediate_IO_Sem
      mov ecx,6
      VMMcall Wait_Semaphore
      cmp dword ptr [ebx+8],0FFFFFFFFh
      clc
      jnz short loc_59
      stc

   loc_59:
      popa
      retn

   loc_60:
      clc
      popa
      retn

   PageSwap_Immediate_IO endp

   If you compare this to the source code that's in the DDK, you'll see that
   this is functionally equivalent to the DDK version, but that it has a 
   chunk of new code in the middle that is jumped around, and not actually
   executed.

   Just following this function there is about 3k of object code (around 
   a thousand lines of disassembled listing) in one procedure that isn't
   referenced anywhere.  I haven't analyzed this section fully, but I 
   suspect that this might be the compression code.  It does seem to be 
   dealing with 4k blocks of memory quite freqently.

New function:  A PM and V86 API proc, that pretty much hardcodes some 
return values.  Reproduced here entirely.


   PageSwap_PM_V86_API_Proc proc near
      VMMcall Log_Proc_Call
      movzx eax, word ptr [ebp+1Ch]
      mov ax, 0Ch
      mov word ptr [ebp+14h],ax
      mov ax, 16h
      mov word ptr [ebp+18h],ax
      retn
   PageSwap_PM_V86_API_Proc endp


PageSwap_Device_Init:

   PageSwap_Device_Init was changed primarily to read in the various 
   SoftRam ini file parameters, even though most of them aren't actually
   used anywhere.  Additionally, it initializes a few variables that
   are referenced in the unexplained 3k of code that isn't called anywhere.
   It also allocates a few pages of memory for its own use that isn't 
   evidently used anywhere.




