Thanks to Rick Segal's posting in the Undoc Corner, and the posting's mention of a file, DCISVGA.DRV, I was able to find out a lot about what's happening in the Apple vs. Intel/Microsoft case. Here are some notes I've typed up. The bottom line is that Intel/Microsoft are shipping code, part of which is byte-for-byte identical with code that is in Apple's QuickTime for Windows. Seems like someone sold their code to Apple, and then sold some of it *again* to Intel/Microsoft (sort of like "The Producers"). What blame there is on Microsoft's or Intel's part, I don't know, but Microsoft/Intel sure seem to be shipping code that is Apple copyright. Even if the code is totally insignificant (as Microsoft seems to claim), it would make no difference in a copyright case. Notes on similarities between QTVHDW.DLL (Apple QuickTime for Windows) and DCISVGA.DRV (Microsoft/Intel Video for Windows) ------------------------------------------------------------- by Andrew Schulman 707-528-0609 76320.302@compuserve.com February 22, 1995 The "Microsoft Q&A: Apple Video For Windows Lawsuit" (February 21, 1995), posted by Rick Segal of Microsoft in the "Undocumented Corner" on the Dr. Dobb's Journal on Compuserve, says that: "The code that appears to be in question is low-level assembly code which programs the registers of specific graphics chips. Generally this code is derived from the reference manuals, data books, and sample code which is provided by the graphics chip vendors. It is not clear at this point as to the origin and the ownership of the code in question. "Q7: Where is the disputed code found? "A: The disputed code is contained in a file called DCISVGA.DRV. This driver is called by the implementation of DCI ("Display Control Interface") that is part of Video For Windows 1.1d." If DCISVGA.DRV indeed is the only Microsoft file in question, the next question then is: What is the supposed equivalent file in Quick Time for Windows? I ran my EXEMAP utility from "Undocumented Windows" on Microsoft's DCISVGA.DRV (\WIN31\DCI\DISK1\DEVKIT\BIN\DCISVGA.DRV on the Microsoft Developer Network Development Platform CD-ROM, January 1995, Disc 1), which is a fairly small file (18384 bytes, dated 8-24-94 4:22pm, "Copyright (c) 1994 Intel/Microsoft Corporation", version 1.00.003), and turned up the following block of API calls: /* 5:0092 */ x = __C000H; /* 5:00d2 */ ShowCursor(); /* 5:0102 */ ShowCursor(); /* 5:0191 */ x = __A000H; /* 5:0217 */ GetProcAddress(); /* 5:0237 */ GetProcAddress(); /* 5:0256 */ x = __C000H; /* 5:0276 */ GetModuleHandle(); /* 5:0282 */ GetModuleHandle(); /* 5:02da */ AllocSelector(); /* 5:0309 */ SETSELECTORBASE(); /* 5:03cc */ SETSELECTORBASE(); /* 5:03f3 */ FreeSelector(); I next ran EXEMAP on all the Apple QuickTime *.DLL and *.QTC files (QTW 1.1, 6-18-93, 12:00 am). I found the following set of API calls, identical to those in the DCISVGA code (merely at different addresses) in Apple's QTVHDW.DLL (9,808 bytes). QTVHDW.DLL is the QuickTime "virtual hardware" module, version 1.10, "(c) Apple Computer, Inc. 1988-93. All rights reserved.": /* 1:0312 */ x = __C000H; /* 1:0352 */ ShowCursor(); /* 1:0382 */ ShowCursor(); /* 1:0405 */ x = __A000H; /* 1:04e8 */ GetProcAddress(); /* 1:0508 */ GetProcAddress(); /* 1:0527 */ x = __C000H; /* 1:0547 */ GetModuleHandle(); /* 1:0553 */ GetModuleHandle(); /* 1:05ab */ AllocSelector(); /* 1:05da */ SETSELECTORBASE(); /* 1:05e7 */ SETSELECTORLIMIT(); /* 1:069c */ SETSELECTORBASE(); /* 1:06d2 */ SETSELECTORBASE(); /* 1:06ed */ FreeSelector(); This is an identical set of Windows API calls, simply located at different addresses. Next, I disassembled (using my commercially-available product, the "Windows Source" add-in to Sourcer, available from V Communications) both Apple's QTVHDW.DLL and Intel/Microsoft's DCISVGA.DRV. I found a lot of code that is absolutely identical, merely located at different addresses. There are many examples, the following is just one. First the original Apple code: ;;; QTVHDW.DLL (version 1.10) ;;; "(c) Apple Computer, Inc. 1988-93. All rights reserved." 2.006A db 'DISPLAY', 0 2.0072 db 'MACH32', 0 2.0079 db 'ATIVersion', 0 2.0084 db 'ATIConfiguration', 0 2.0095 db 'ATIXYtoLinear' 2.00A2 db 0, 0 2.00A4 db '761295520' 2.00AD db 0 1.0519 push bp 1.051A mov bp,sp 1.051C add sp,0FFFEh 1.051F push es 1.0520 push si 1.0521 push di 1.0522 mov si,offset data_0055 ; (2.0060='761295520') 1.0525 lea di,cs:[312h] ;;; __C000H 1.0529 mov es,di 1.052B mov di,data_0023e ; (0312:0031=5Fh) 1.052E mov cx,0Ah 1.0531 cld 1.0532 repe cmpsb 1.0534 jnz loc_0030 1.0538 test byte ptr es:data_0024e,40h ; (0312:0044=0Eh) '@' 1.053E jnz loc_0030 1.0542 push ds 1.0543 push 6Ah ;;; 'DISPLAY' 1.0546 call far ptr GetModuleHandle 1.054B mov data_0050,ax ; (2.0054=0) 1.054E push ds 1.054F push 72h ;;; 'MACH32' 1.0552 call far ptr GetModuleHandle 1.0557 mov data_0051,ax ; (2.0056=0) 1.055A push 79h ; PARAMETER_1 ;;; 'ATIVersion' 1.055D call sub_0003 ; (04D8) 1.0560 test eax,eax 1.0563 jz loc_0030 1.0567 push 84h ; PARAMETER_1 ;;; 'ATIConfiguration' 1.056A call sub_0003 ; (04D8) 1.056D test eax,eax 1.0570 jz loc_0030 1.0574 mov data_0045,eax ; (2.0040=0) 1.0578 push 95h ; PARAMETER_1 ;;; 'ATIXYtoLinear' 1.057B call sub_0003 ; (04D8) 1.057E test eax,eax 1.0581 jz loc_0030 1.0585 mov dword ptr data_0046,eax ; (2.0044=0) 1.0589 mov ax,1684h 1.058C xor di,di 1.058E mov es,di 1.0590 mov bx,30h 1.0593 int 2Fh ; Get device API entry point for ; ID bx, returns ptr in es:di 1.0595 mov ax,es 1.0597 shl edi,10h 1.059B shrd edi,eax,10h 1.05A0 jz loc_0030 1.05A4 mov data_0047,edi ; (2.0048=0) 1.05A9 push ds 1.05AA call far ptr AllocSelector 1.05AF test ax,ax 1.05B1 jz short loc_0030 1.05B3 mov data_0052,ax ; (2.0058=0) 1.05B6 mov ax,2 1.05B9 call dword ptr data_0047 ; (2.0048=0) 1.05BD mov [bp-2],ax 1.05C0 test al,4 1.05C2 jnz short loc_0027 1.05C4 sgdt fword ptr data_0053 ; (2.005A=0) 1.05C9 jmp short loc_0028 ; (05D0) 1.05CB loc_0027: ; xref 1.05C2 1.05CB sldt data_0053 ; (2.005A=0) 1.05D0 loc_0028: ; xref 1.05C9 1.05D0 push data_0052 ; (2.0058=0) 1.05D4 push dword ptr data_0053+2 ; (2.005C=0) 1.05D9 call far ptr SETSELECTORBASE 1.05DE push data_0052 ; (2.0058=0) 1.05E2 push 0 1.05E4 push 0FFFFh 1.05E6 call far ptr SETSELECTORLIMIT 1.05EB mov es,data_0052 ; (2.0058=0) 1.05EF mov bx,[bp-2] 1.05F2 and bl,0F8h 1.05F5 mov eax,es:[bx+1] 1.05FA mov al,es:[bx+7] 1.05FE ror eax,8 1.0602 mov data_0048,eax ; (2.004C=0) 1.0606 mov ax,3 1.0609 mov bx,[bp-2] 1.060C call dword ptr data_0047 ; (2.0048=0) 1.0610 push 0 1.0612 push 0 1.0614 call dword ptr data_0046 ; (2.0044=0) 1.0618 add data_0048,eax ; (2.004C=0) 1.061D mov al,1 1.061F loc_0029: ; xref 1.0628 1.061F pop di 1.0620 pop si 1.0621 pop es 1.0622 mov sp,bp 1.0624 pop bp 1.0625 retf 1.0626 loc_0030: ; xref 1.0534, 053E, 0563, 0570 ; 0581, 05A0, 05B1 1.0626 xor ax,ax 1.0628 jmp short loc_0029 ; (061F) Okay, that's some code from Apple QuickTime. To summarize what it does: stuff GetModuleHandle "DISPLAY" GetModuleHandle "MACH32" sub_0003 "ATIVersion" sub_0003 "ATIConfiguration" sub_0003 "ATIXYtoLinear" INT 2Fh/1684h/30h -> data_0047 AllocSelector call data_0047 ax = 2 sgdt sldt SetSelectorBase SetSelectorLimit call data_0047 ax = 3 call data_0046 Then in Intel/Microsoft's DCISVGA.LST, we have: ;;; from Intel/Microsoft DCISVGA.DRV (version 1.00.003) ;;; "Copyright (c) 1994 Intel/Microsoft Corporation" 9.00A8 db 'DISPLAY', 0 9.00B0 db 'MACH32', 0 9.00B7 db 'ATIVersion', 0 9.00C2 db 'ATIConfiguration', 0 9.00D3 db 'ATIXYtoLinear' 9.00E0 db 0, 0 9.00E2 data_0071 db '761295520', 0 ; xref 5.0469 ;* No entry point to code 5.0248 push bp 5.0249 mov bp,sp 5.024B add sp,0FFFEh 5.024E push es 5.024F push si 5.0250 push di 5.0251 mov si,offset data_0070 ; (9.009E='761295520') 5.0254 lea di,cs:[92h] 5.0258 mov es,di 5.025A mov di,data_0025e ; (0092:0031=0) 5.025D mov cx,0Ah 5.0260 cld 5.0261 repe cmpsb 5.0263 jnz loc_0137 5.0267 test byte ptr es:data_0026e,40h ; (0092:0044=0) '@' 5.026D jnz loc_0137 5.0271 push ds 5.0272 push 0A8h 5.0275 call far ptr GetModuleHandle 5.027A mov data_0066,ax ; (9.0094=0) 5.027D push ds 5.027E push 0B0h 5.0281 call far ptr GetModuleHandle 5.0286 mov data_0067,ax ; (9.0096=0) 5.0289 push 0B7h ; PARAMETER_1 5.028C call sub_0020 ; (0207) 5.028F test eax,eax 5.0292 jz loc_0137 5.0296 push 0C2h ; PARAMETER_1 5.0299 call sub_0020 ; (0207) 5.029C test eax,eax 5.029F jz loc_0137 5.02A3 mov data_0061,eax ; (9.0080=0) 5.02A7 push 0D3h ; PARAMETER_1 5.02AA call sub_0020 ; (0207) 5.02AD test eax,eax 5.02B0 jz loc_0137 5.02B4 mov data_0062,eax ; (9.0084=0) 5.02B8 mov ax,1684h 5.02BB xor di,di 5.02BD mov es,di 5.02BF mov bx,30h 5.02C2 int 2Fh ; Get device API entry point for ; ID bx, returns ptr in es:di 5.02C4 mov ax,es 5.02C6 shl edi,10h 5.02CA shrd edi,eax,10h 5.02CF jz loc_0137 5.02D3 mov data_0063,edi ; (9.0088=0) 5.02D8 push ds 5.02D9 call far ptr AllocSelector 5.02DE test ax,ax 5.02E0 jz short loc_0137 5.02E2 mov data_0141,ax ; (9.02E6=0) 5.02E5 mov ax,2 5.02E8 call dword ptr data_0063 ; (9.0088=0) 5.02EC mov [bp-2],ax 5.02EF test al,4 5.02F1 jnz short loc_0134 5.02F3 sgdt fword ptr data_0068 ; (9.0098=0) 5.02F8 jmp short loc_0135 ; (02FF) 5.02FA loc_0134: ; xref 5.02F1 5.02FA sldt data_0068 ; (9.0098=0) 5.02FF loc_0135: ; xref 5.02F8 5.02FF push data_0141 ; (9.02E6=0) 5.0303 push dword ptr data_0068+2 ; (9.009A=0) 5.0308 call far ptr SETSELECTORBASE 5.030D push data_0141 ; PARAMETER_3 (9.02E6=0) 5.0311 push 40h ; PARAMETER_2 5.0313 push 0 ; PARAMETER_1 5.0315 call far ptr sub_0012 ; (3.0448) 5.031A mov es,data_0141 ; (9.02E6=0) 5.031E mov bx,[bp-2] 5.0321 and bl,0F8h 5.0324 mov eax,es:[bx+1] 5.0329 mov al,es:[bx+7] 5.032D ror eax,8 5.0331 mov data_0064,eax ; (9.008C=0) 5.0335 mov ax,3 5.0338 mov bx,[bp-2] 5.033B call dword ptr data_0063 ; (9.0088=0) 5.033F push 0 5.0341 push 0 5.0343 call dword ptr data_0062 ; (9.0084=0) 5.0347 add data_0064,eax ; (9.008C=0) 5.034C mov al,1 5.034E mov byte ptr data_0050,1 ; (9.0010=0) 5.0353 loc_0136: ; xref 5.035C 5.0353 pop di 5.0354 pop si 5.0355 pop es 5.0356 mov sp,bp 5.0358 pop bp 5.0359 retf 5.035A loc_0137: ; xref 5.0263, 026D, 0292, 029F ; 02B0, 02CF, 02E0 5.035A xor ax,ax 5.035C jmp short loc_0136 ; (0353) This Intel/Microsoft code is basically: stuff GetModuleHandle "DISPLAY" GetModuleHandle "MACH32" sub_0020 "ATIVersion" sub_0020 "ATIConfiguration" sub_0020 "ATIXYtoLinear" INT 2Fh/1684h/30h -> data_0063 AllocSelector call data_0063 ax = 2 sgdt sldt SetSelectorBase sub_0012 call data_0063 ax = 3 Hard to know what to make of these identical blocks of code (perhaps they belong neither to Canyon, Apple, Microsoft, or Intel, but instead come from some unknown common source???), but they certainly are identical. To emphasize, there are many other similarities in these files; this is just one example. The really strange thing is that Microsoft provides some source code for what's found in DCISVGA.DRV, as part of the Video for Windows development kit, in \WIN31\DCI\DISK1\DEVKIT\BIN\SAMPLE. For example the file ATI68800.ASM has the following header: ************************************************************************ * * * Copyright (c) 1992 Intel Corporation * * All Rights Reserved * * * * INTEL CORPORATION PROPRIETARY INFORMATION * * * * This software is supplied under the terms of a licence * * agreement with Intel Corporation and may not be copied nor * * disclosed except in accordance with the terms of that agreement. * * * ************************************************************************ Yet, this source file contains code identical to that found in Apple's QTVHDW.DLL. For example, we find the source code corresponding to that shown above: COMMENT @ Function Identify: Determine if this hardware routine matches the current adapter and driver Returns: AX = TRUE hardware matches FALSE hardware does not match @ EXTERN PASCAL ALLOCSELECTOR:FAR EXTERN PASCAL SETSELECTORBASE:FAR EXTERN PASCAL SETSELECTORLIMIT:FAR Identify PROC FAR USES ES SI DI LOCAL SelMagic:WORD ; ATI linear magic selector mov si, OFFSET EyeCatch lea di, _C000h ; Get selector of video BIOS mov es, di ; mov di, 31H ; Fixed offset in ATI BIOS mov cx, SIZEOF EyeCatch ; Get length of string cld ; Search forwards repz cmpsb ; Does the signature match? jne NoMatch ; Skip if no match test BYTE PTR es:[44H], 40H ; Bit off means graphics engine present jnz NoMatch ; ATI 68800 has a graphics engine push ds ; push OFFSET szDISP ; Look for DISPLAY module call GETMODULEHANDLE ; mov hModDISP, ax ; Save the module handle push ds ; push OFFSET szMACH ; Look for MACH32 module call GETMODULEHANDLE ; mov hModMACH, ax ; Save the module handle push OFFSET Version ; Get address of ATIVersion entry point call GetEntryPoint ; test eax, eax ; Was entry point found? je NoMatch ; Skip if entry point not found ; Ignore address of ATIVersion entry point push OFFSET Config ; Get address of ATIConfiguration entry point call GetEntryPoint ; test eax, eax ; Was entry point found? je NoMatch ; Skip if entry point not found mov AdConfig, eax ; Save address of ATIConfiguration entry point push OFFSET XYToLin ; Get address of ATIXYtoLinear entry point call GetEntryPoint ; test eax, eax ; Was entry point found? je NoMatch ; Skip if entry point not found mov AdXYLin, eax ; Save address of ATIXYtoLinear entry point mov ax, 1684H ; Get VXD device API entry point xor di, di ; mov es, di ; mov bx, 30H ; VXD ID int 2FH ; mov ax, es ; Put the returned address in EDI shl edi, 16 ; shrd edi, eax, 16 ; jz NoMatch ; Skip if VXD device API entry point not found mov AdVXD, edi ; Save VXD device API entry point push ds ; Copy ds, a read/write 16-bit expand-up call ALLOCSELECTOR ; data segment test ax, ax ; Was selector allocated? jz NoMatch ; Skip if selector was not allocated mov Selector, ax ; Save the selector mov ax, 2 ; Allocate the linear magic selector call [AdVXD] ; mov SelMagic, ax ; Save the selector test al, 4 ; Is magic selector from LDT? jnz UseLDT ; Skip if magic selector is from LDT sgdt LimitXDT ; Get the GDT address and limit jmp GotDT ; Skip to common GDT/LDT handling UseLDT: sldt LimitXDT ; Get the LDT address and limit GotDT: ; Assign selector to GDT or LDT for now push Selector ; Set the selector base push BaseXDT ; call SETSELECTORBASE ; ;; BUGBUG : following is used to set selector limit - extracted from ;; Todd Laney's code push Selector ; Set the selector limit push 40H ; High word of selector limit push 0 ; Low word ; call SETSELECTORLIMIT ; call SETSELLIMIT ; call Todd's routine mov es, Selector ; Point to the GDT or LDT mov bx, SelMagic ; Inspect the linear magic selector and bl, 0F8H ; Remove TI, RPL bits mov eax, es:[BX+1] ; Get the selector base mov al, es:[BX+7] ; ror eax, 8 ; mov LinBase, eax ; Save the linear address mov ax, 3 ; Free the linear magic selector mov bx, SelMagic ; call [AdVXD] ; push 0 ; Push (0,0) push 0 ; call [AdXYLin] ; add LinBase, eax ; Compute first linear address in frame buffer mov al, 1 ; Set return code to TRUE mov gHdwCur, 1 ; set hardware cursor to TRUE Exit: ret ; Return to caller NoMatch: xor ax, ax ; Set return code to FALSE jmp Exit ; Go to common exit Identify ENDP From the appearance of this exact same code in QTVHDW.DLL, it would appear that the above code is actually copyright Apple, with the word "Apple" crossed off and the word "Intel" written in, and without the date (1992) changed. === end ===