121 added + 198 modified, total 319 files
- TODO:
- FIXME Other possible values of AvMode:
- FIXME */
- FIXME */
- FIXME: return STATUS_INSUFFICIENT_RESOURCES if the NumberOfMapRegisters
- FIXME: We propably shouldn't allocate the memory here for common
- TODO: Allocation */
- FIXME.
- FIXME: Handle case when doing common-buffer System DMA. In this case,
- TODO:
- FIXME: screen size should be read from the boot parameters */
- TODO: Initialize the first Map Buffer */
- TODO:
- FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
- TODO:
- FIXME These are also defined in drivers/bus/pci/pcidef.h.
- FIXME: Should handle 64-bit addresses */
- FIXME I have no idea... */
- FIXME Just a guess */
- FIXME I have no idea... */
- FIXME Just a guess */
- FIXME Just a guess */
- FIXME Just a guess */
- FIXME: Should store the resources in the registry resource map */
- FIXME: Report all resources used by hal.
- FIXME:
- FIXME:
- FIXME: Report all resources used by hal.
- FIXME Other possible values of AvMode:
- TODO:
- FIXME (%s, %p): not verifying image\n", lpszImage, pData);
- FIXME: Not sure what the pbContextInfo field is for.
- FIXME: The presence of the SigInFile value indicates the
- FIXME: This definition of DWORD2BE is little endian specific! */
- FIXME: This definition of blk0 is little endian specific! */
- FIXME("(void): stub\n");
- FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid),
- FIXME("(void): stub\n");
- FIXME("(void): stub\n");
- FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
- FIXME: remove values from the string table on error */
- FIXME: strdupW it? */
- FIXME("don't support persist files yet\b");
- FIXME("open failed r = %08lx!\n",r);
- FIXME("Failed to stat storage\n");
- FIXME("Failed to allocate a handle\n");
- FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
- FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
- FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
- FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
- FIXME: check return code */
- FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
- FIXME("%s 0x%08lx\n", debugstr_a(szProduct), dwReinstallMode);
- FIXME("%s 0x%08lx\n", debugstr_w(szProduct), dwReinstallMode);
- FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage), eInstallType, debugstr_a(szCommandLine));
- FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage), eInstallType, debugstr_w(szCommandLine));
- FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
- FIXME("%s %d %d\n",debugstr_w(szProduct), iInstallLevel, eInstallState);
- FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
- FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
- FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute), szBuffer, pcchValueBuf);
- FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute), szBuffer, pcchValueBuf);
- FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
- FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
- FIXME("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
- FIXME("%s\n", debugstr_a(szProduct));
- FIXME("%s\n", debugstr_w(szProduct));
- FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
- FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e);
- FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e);
- FIXME("%s\n",debugstr_w(lpBuffer));
- FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
- FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
- FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),uType,wLanguageId,f);
- FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);*/
- FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),uType,wLanguageId,f);
- FIXME("%lx %s\n", hDatabase, debugstr_a(szTableName));
- FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
- FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
- FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
- FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
- FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
- FIXME: lock the database */
- FIXME: unlock the database */
- FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);
- FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);
- FIXME("%ld %x %ld\n",hView, eModifyMode, hRecord);
- FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
- FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
- FIXME("%ld %d\n", hRecord, iField);
- FIXME("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);
- FIXME("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);
- FIXME("%ld %d %s\n", hRecord, iField, debugstr_a(szFilename));
- FIXME("%ld %d %s\n", hRecord, iField, debugstr_w(szFilename));
- FIXME: free $1 */
- FIXME("LOCALIZABLE ignored\n");
- FIXME */
- FIXME("%ld %p\n",hSummaryInfo, pCount);
- FIXME("Unknown property variant type\n");
- FIXME("%ld %d %p %p %p %p %p\n",
- FIXME: memory leak */
- FIXME: memory leak */
- FIXME: check we're comparing a string to a column */
- FIXME: This fails on native; it shouldn't though - native bug?
reactos
diff -u -r1.262.2.2 -r1.262.2.3
--- Makefile 13 Dec 2004 09:38:44 -0000 1.262.2.2
+++ Makefile 13 Dec 2004 16:17:57 -0000 1.262.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.262.2.2 2004/12/13 09:38:44 hyperion Exp $
+# $Id: Makefile,v 1.262.2.3 2004/12/13 16:17:57 hyperion Exp $
#
# Global makefile
#
reactos/drivers/dd/null
diff -u -r1.19.10.2 -r1.19.10.3
--- makefile 13 Dec 2004 09:38:46 -0000 1.19.10.2
+++ makefile 13 Dec 2004 16:17:58 -0000 1.19.10.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.19.10.2 2004/12/13 09:38:46 hyperion Exp $
+# $Id: makefile,v 1.19.10.3 2004/12/13 16:17:58 hyperion Exp $
PATH_TO_TOP = ../../..
reactos/drivers/fs/cdfs
diff -u -r1.7.28.1 -r1.7.28.2
--- common.c 13 Dec 2004 09:38:46 -0000 1.7.28.1
+++ common.c 13 Dec 2004 16:17:58 -0000 1.7.28.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: common.c,v 1.7.28.1 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: common.c,v 1.7.28.2 2004/12/13 16:17:58 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.15.6.2 -r1.15.6.3
--- cleanup.c 13 Dec 2004 09:38:46 -0000 1.15.6.2
+++ cleanup.c 13 Dec 2004 16:17:58 -0000 1.15.6.3
@@ -1,4 +1,4 @@
-/* $Id: cleanup.c,v 1.15.6.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: cleanup.c,v 1.15.6.3 2004/12/13 16:17:58 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.75.2.2 -r1.75.2.3
--- create.c 13 Dec 2004 09:38:46 -0000 1.75.2.2
+++ create.c 13 Dec 2004 16:17:58 -0000 1.75.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: create.c,v 1.75.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: create.c,v 1.75.2.3 2004/12/13 16:17:58 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/create.c
reactos/drivers/fs/vfat
diff -u -r1.35.2.2 -r1.35.2.3
--- dir.c 13 Dec 2004 09:38:46 -0000 1.35.2.2
+++ dir.c 13 Dec 2004 16:17:58 -0000 1.35.2.3
@@ -1,5 +1,5 @@
/*
- * $Id: dir.c,v 1.35.2.2 2004/12/13 09:38:46 hyperion Exp $
+ * $Id: dir.c,v 1.35.2.3 2004/12/13 16:17:58 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.17.8.2 -r1.17.8.3
--- direntry.c 13 Dec 2004 09:38:46 -0000 1.17.8.2
+++ direntry.c 13 Dec 2004 16:17:58 -0000 1.17.8.3
@@ -1,4 +1,4 @@
-/* $Id: direntry.c,v 1.17.8.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: direntry.c,v 1.17.8.3 2004/12/13 16:17:58 hyperion Exp $
*
*
* FILE: DirEntry.c
reactos/drivers/fs/vfat
diff -u -r1.42.2.2 -r1.42.2.3
--- dirwr.c 13 Dec 2004 09:38:46 -0000 1.42.2.2
+++ dirwr.c 13 Dec 2004 16:17:58 -0000 1.42.2.3
@@ -1,4 +1,4 @@
-/* $Id: dirwr.c,v 1.42.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: dirwr.c,v 1.42.2.3 2004/12/13 16:17:58 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.46.8.2 -r1.46.8.3
--- fat.c 13 Dec 2004 09:38:46 -0000 1.46.8.2
+++ fat.c 13 Dec 2004 16:17:58 -0000 1.46.8.3
@@ -1,5 +1,5 @@
/*
- * $Id: fat.c,v 1.46.8.2 2004/12/13 09:38:46 hyperion Exp $
+ * $Id: fat.c,v 1.46.8.3 2004/12/13 16:17:58 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.42.2.2 -r1.42.2.3
--- fcb.c 13 Dec 2004 09:38:46 -0000 1.42.2.2
+++ fcb.c 13 Dec 2004 16:17:58 -0000 1.42.2.3
@@ -1,4 +1,4 @@
-/* $Id: fcb.c,v 1.42.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: fcb.c,v 1.42.2.3 2004/12/13 16:17:58 hyperion Exp $
*
*
* FILE: drivers/fs/vfat/fcb.c
reactos/drivers/fs/vfat
diff -u -r1.38.2.2 -r1.38.2.3
--- finfo.c 13 Dec 2004 09:38:46 -0000 1.38.2.2
+++ finfo.c 13 Dec 2004 16:17:59 -0000 1.38.2.3
@@ -1,4 +1,4 @@
-/* $Id: finfo.c,v 1.38.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: finfo.c,v 1.38.2.3 2004/12/13 16:17:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.36.2.2 -r1.36.2.3
--- fsctl.c 13 Dec 2004 09:38:46 -0000 1.36.2.2
+++ fsctl.c 13 Dec 2004 16:17:59 -0000 1.36.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: fsctl.c,v 1.36.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: fsctl.c,v 1.36.2.3 2004/12/13 16:17:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.14.2.2 -r1.14.2.3
--- misc.c 13 Dec 2004 09:38:46 -0000 1.14.2.2
+++ misc.c 13 Dec 2004 16:17:59 -0000 1.14.2.3
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.14.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: misc.c,v 1.14.2.3 2004/12/13 16:17:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.71.2.2 -r1.71.2.3
--- rw.c 13 Dec 2004 09:38:46 -0000 1.71.2.2
+++ rw.c 13 Dec 2004 16:17:59 -0000 1.71.2.3
@@ -1,5 +1,5 @@
-/* $Id: rw.c,v 1.71.2.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: rw.c,v 1.71.2.3 2004/12/13 16:17:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.8.34.2 -r1.8.34.3
--- shutdown.c 13 Dec 2004 09:38:46 -0000 1.8.34.2
+++ shutdown.c 13 Dec 2004 16:17:59 -0000 1.8.34.3
@@ -1,4 +1,4 @@
-/* $Id: shutdown.c,v 1.8.34.2 2004/12/13 09:38:46 hyperion Exp $
+/* $Id: shutdown.c,v 1.8.34.3 2004/12/13 16:17:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/fs/vfat
diff -u -r1.69.2.2 -r1.69.2.3
--- vfat.h 13 Dec 2004 09:38:46 -0000 1.69.2.2
+++ vfat.h 13 Dec 2004 16:17:59 -0000 1.69.2.3
@@ -1,4 +1,4 @@
-/* $Id: vfat.h,v 1.69.2.2 2004/12/13 09:38:46 hyperion Exp $ */
+/* $Id: vfat.h,v 1.69.2.3 2004/12/13 16:17:59 hyperion Exp $ */
#include <ddk/ntifs.h>
reactos/drivers/fs/vfat
diff -u -r1.27.2.2 -r1.27.2.3
--- volume.c 13 Dec 2004 09:38:47 -0000 1.27.2.2
+++ volume.c 13 Dec 2004 16:17:59 -0000 1.27.2.3
@@ -1,4 +1,4 @@
-/* $Id: volume.c,v 1.27.2.2 2004/12/13 09:38:47 hyperion Exp $
+/* $Id: volume.c,v 1.27.2.3 2004/12/13 16:17:59 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/lib/ip
diff -u -r1.7.2.2 -r1.7.2.3
--- makefile 13 Dec 2004 09:38:47 -0000 1.7.2.2
+++ makefile 13 Dec 2004 16:18:00 -0000 1.7.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.7.2.2 2004/12/13 09:38:47 hyperion Exp $
+# $Id: makefile,v 1.7.2.3 2004/12/13 16:18:00 hyperion Exp $
PATH_TO_TOP = ../../..
reactos/drivers/lib/ip/transport/tcp
diff -u -r1.9.2.2 -r1.9.2.3
--- tcp.c 13 Dec 2004 09:38:47 -0000 1.9.2.2
+++ tcp.c 13 Dec 2004 16:18:00 -0000 1.9.2.3
@@ -144,131 +144,6 @@
}
}
-static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection,
- ULONG NewState ) {
- NTSTATUS Status = STATUS_SUCCESS;
- PTCP_COMPLETION_ROUTINE Complete;
- PTDI_BUCKET Bucket;
- PLIST_ENTRY Entry;
- BOOLEAN CompletedOne = FALSE;
-
- /* Things that can happen when we try the initial connection */
- if( ((NewState & SEL_CONNECT) || (NewState & SEL_FIN)) &&
-
- !(Connection->State & (SEL_CONNECT | SEL_FIN)) ) {
- while( !IsListEmpty( &Connection->ConnectRequest ) ) {
- Connection->State |= NewState & (SEL_CONNECT | SEL_FIN);
- Entry = RemoveHeadList( &Connection->ConnectRequest );
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Connect Request %x\n", Bucket->Request));
- if( NewState & SEL_FIN ) Status = STATUS_CONNECTION_REFUSED;
- Complete( Bucket->Request.RequestContext, Status, 0 );
- /* Frees the bucket allocated in TCPConnect */
- PoolFreeBuffer( Bucket );
- }
- }
-
- /* Things that happen after we're connected */
- if( (NewState & SEL_READ) ) {
- TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
- IsListEmpty(&Connection->ReceiveRequest) ?
- "empty" : "nonempty"));
-
- while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
- PIRP Irp;
- OSK_UINT RecvLen = 0, Received = 0;
- OSK_PCHAR RecvBuffer = 0;
- PMDL Mdl;
- NTSTATUS Status;
-
- Entry = RemoveHeadList( &Connection->ReceiveRequest );
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
-
- TI_DbgPrint(DEBUG_TCP,
- ("Readable, Completing read request %x\n",
- Bucket->Request));
-
- Irp = Bucket->Request.RequestContext;
- Mdl = Irp->MdlAddress;
-
- TI_DbgPrint(DEBUG_TCP,
- ("Getting the user buffer from %x\n", Mdl));
-
- NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
-
- TI_DbgPrint(DEBUG_TCP,
- ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
-
- TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
- TI_DbgPrint
- (DEBUG_TCP,
- ("Connection->SocketContext: %x\n",
- Connection->SocketContext));
- TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
-
- Status = TCPTranslateError
- ( OskitTCPRecv( Connection->SocketContext,
- RecvBuffer,
- RecvLen,
- &Received,
- 0 ) );
-
- TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
-
- if( Status == STATUS_SUCCESS ) {
- TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
- Received, Status));
-
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Receive Request: %x\n",
- Bucket->Request));
-
- Complete( Bucket->Request.RequestContext,
- STATUS_SUCCESS, Received );
- CompletedOne = TRUE;
- } else if( Status == STATUS_PENDING ) {
- InsertHeadList( &Connection->ReceiveRequest,
- &Bucket->Entry );
- break;
- } else {
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Receive request: %x %x\n",
- Bucket->Request, Status));
- Complete( Bucket->Request.RequestContext, Status, 0 );
- CompletedOne = TRUE;
- }
- }
- }
- if( NewState & SEL_FIN ) {
- TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
-
- while( !IsListEmpty( &Connection->ReceiveRequest ) ) {
- Entry = RemoveHeadList( &Connection->ReceiveRequest );
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
-
- Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
- }
- }
-
- Connection->Signalled = FALSE;
-}
-
-VOID DrainSignals() {
- PCONNECTION_ENDPOINT Connection;
- PLIST_ENTRY ListEntry;
-
- while( !IsListEmpty( &SignalledConnections ) ) {
- ListEntry = RemoveHeadList( &SignalledConnections );
- Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT,
- SignalList );
- HandleSignalledConnection( Connection, Connection->SignalState );
- }
-}
-
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
PCONNECTION_ENDPOINT Connection =
ExAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT));
reactos/drivers/net/afd/afd
diff -u -r1.5.2.2 -r1.5.2.3
--- connect.c 13 Dec 2004 09:38:48 -0000 1.5.2.2
+++ connect.c 13 Dec 2004 16:18:00 -0000 1.5.2.3
@@ -1,4 +1,4 @@
-/* $Id: connect.c,v 1.5.2.2 2004/12/13 09:38:48 hyperion Exp $
+/* $Id: connect.c,v 1.5.2.3 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/connect.c
reactos/drivers/net/afd/afd
diff -u -r1.4.8.2 -r1.4.8.3
--- info.c 13 Dec 2004 09:38:48 -0000 1.4.8.2
+++ info.c 13 Dec 2004 16:18:00 -0000 1.4.8.3
@@ -1,4 +1,4 @@
-/* $Id: info.c,v 1.4.8.2 2004/12/13 09:38:48 hyperion Exp $
+/* $Id: info.c,v 1.4.8.3 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/info.c
reactos/drivers/net/afd/afd
diff -u -r1.13.2.2 -r1.13.2.3
--- main.c 13 Dec 2004 09:38:48 -0000 1.13.2.2
+++ main.c 13 Dec 2004 16:18:00 -0000 1.13.2.3
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.13.2.2 2004/12/13 09:38:48 hyperion Exp $
+/* $Id: main.c,v 1.13.2.3 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/main.c
reactos/drivers/net/afd/afd
diff -u -r1.12.2.2 -r1.12.2.3
--- read.c 13 Dec 2004 09:38:49 -0000 1.12.2.2
+++ read.c 13 Dec 2004 16:18:00 -0000 1.12.2.3
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.12.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: read.c,v 1.12.2.3 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/read.c
reactos/drivers/net/afd/afd
diff -u -r1.7.2.2 -r1.7.2.3
--- select.c 13 Dec 2004 09:38:49 -0000 1.7.2.2
+++ select.c 13 Dec 2004 16:18:00 -0000 1.7.2.3
@@ -1,4 +1,4 @@
-/* $Id: select.c,v 1.7.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: select.c,v 1.7.2.3 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/select.c
reactos/drivers/net/afd/afd
diff -u -r1.5.2.1 -r1.5.2.2
--- tdiconn.c 13 Dec 2004 09:38:49 -0000 1.5.2.1
+++ tdiconn.c 13 Dec 2004 16:18:00 -0000 1.5.2.2
@@ -1,4 +1,4 @@
-/* $Id: tdiconn.c,v 1.5.2.1 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: tdiconn.c,v 1.5.2.2 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/tdiconn.c
reactos/drivers/net/afd/afd
diff -u -r1.12.2.2 -r1.12.2.3
--- write.c 13 Dec 2004 09:38:49 -0000 1.12.2.2
+++ write.c 13 Dec 2004 16:18:00 -0000 1.12.2.3
@@ -1,4 +1,4 @@
-/* $Id: write.c,v 1.12.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: write.c,v 1.12.2.3 2004/12/13 16:18:00 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/net/afd/afd/write.c
reactos/drivers/net/afd/include
diff -u -r1.25.2.2 -r1.25.2.3
--- afd.h 13 Dec 2004 09:38:49 -0000 1.25.2.2
+++ afd.h 13 Dec 2004 16:18:00 -0000 1.25.2.3
@@ -1,4 +1,4 @@
-/* $Id: afd.h,v 1.25.2.2 2004/12/13 09:38:49 hyperion Exp $
+/* $Id: afd.h,v 1.25.2.3 2004/12/13 16:18:00 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/drivers/net/afd
diff -u -r1.14.2.2 -r1.14.2.3
--- makefile 13 Dec 2004 09:38:49 -0000 1.14.2.2
+++ makefile 13 Dec 2004 16:18:00 -0000 1.14.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.14.2.2 2004/12/13 09:38:49 hyperion Exp $
+# $Id: makefile,v 1.14.2.3 2004/12/13 16:18:00 hyperion Exp $
PATH_TO_TOP = ../../..
reactos/drivers/net/tcpip/datalink
diff -u -r1.27.2.2 -r1.27.2.3
--- lan.c 13 Dec 2004 09:38:49 -0000 1.27.2.2
+++ lan.c 13 Dec 2004 16:18:00 -0000 1.27.2.3
@@ -354,8 +354,6 @@
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
- ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
if( Status != NDIS_STATUS_SUCCESS ) return;
TcpipAcquireSpinLock( &LanWorkLock, &OldIrql );
reactos/drivers/net/tcpip
diff -u -r1.31.2.2 -r1.31.2.3
--- makefile 13 Dec 2004 09:38:49 -0000 1.31.2.2
+++ makefile 13 Dec 2004 16:18:01 -0000 1.31.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.31.2.2 2004/12/13 09:38:49 hyperion Exp $
+# $Id: makefile,v 1.31.2.3 2004/12/13 16:18:01 hyperion Exp $
PATH_TO_TOP = ../../..
reactos/drivers/video/displays/vga/main
diff -u -r1.3.20.2 -r1.3.20.3
--- enable.c 13 Dec 2004 09:38:50 -0000 1.3.20.2
+++ enable.c 13 Dec 2004 16:18:01 -0000 1.3.20.3
@@ -1,9 +1,9 @@
/*
* entry.c
*
- * $Revision: 1.3.20.2 $
+ * $Revision: 1.3.20.3 $
* $Author: hyperion $
- * $Date: 2004/12/13 09:38:50 $
+ * $Date: 2004/12/13 16:18:01 $
*
*/
reactos/drivers/video/displays/vga/objects
diff -u -r1.3.10.1 -r1.3.10.2
--- pointer.c 13 Dec 2004 09:38:50 -0000 1.3.10.1
+++ pointer.c 13 Dec 2004 16:18:01 -0000 1.3.10.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: pointer.c,v 1.3.10.1 2004/12/13 09:38:50 hyperion Exp $
+/* $Id: pointer.c,v 1.3.10.2 2004/12/13 16:18:01 hyperion Exp $
*
* PROJECT: ReactOS VGA16 display driver
* FILE: drivers/dd/vga/display/objects/pointer.c
reactos/hal/halx86/include
diff -u -r1.15.2.1 -r1.15.2.2
--- hal.h 8 Dec 2004 21:56:56 -0000 1.15.2.1
+++ hal.h 13 Dec 2004 16:18:01 -0000 1.15.2.2
@@ -284,10 +284,10 @@
UCHAR Reserved9[30]; /* 0A2h-0BFh */
/* DMA Controller 2 */
- DMA1_CONTROL DmaController2; /* 0C0h-0DFh */
+ DMA1_CONTROL DmaController2; /* 0C0h-0CFh */
/* System Reserved Ports */
- UCHAR SystemReserved[800]; /* 0E0h-3FFh */
+ UCHAR SystemReserved[816]; /* 0D0h-3FFh */
/* Extended DMA Registers, Controller 1 */
UCHAR DmaHighByteCount1[8]; /* 400h-407h */
reactos/include/ddk
diff -u -r1.46.2.2 -r1.46.2.3
--- iofuncs.h 13 Dec 2004 09:38:50 -0000 1.46.2.2
+++ iofuncs.h 13 Dec 2004 16:18:01 -0000 1.46.2.3
@@ -1,6 +1,6 @@
#ifndef _INCLUDE_DDK_IOFUNCS_H
#define _INCLUDE_DDK_IOFUNCS_H
-/* $Id: iofuncs.h,v 1.46.2.2 2004/12/13 09:38:50 hyperion Exp $ */
+/* $Id: iofuncs.h,v 1.46.2.3 2004/12/13 16:18:01 hyperion Exp $ */
#ifdef __NTOSKRNL__
extern POBJECT_TYPE EXPORTED IoAdapterObjectType;
reactos/include/ddk
diff -u -r1.69.2.2 -r1.69.2.3
--- iotypes.h 13 Dec 2004 09:38:50 -0000 1.69.2.2
+++ iotypes.h 13 Dec 2004 16:18:01 -0000 1.69.2.3
@@ -1,4 +1,4 @@
-/* $Id: iotypes.h,v 1.69.2.2 2004/12/13 09:38:50 hyperion Exp $
+/* $Id: iotypes.h,v 1.69.2.3 2004/12/13 16:18:01 hyperion Exp $
*
*/
reactos/include/ntdll
diff -u -r1.52.2.2 -r1.52.2.3
--- rtl.h 13 Dec 2004 09:38:51 -0000 1.52.2.2
+++ rtl.h 13 Dec 2004 16:18:01 -0000 1.52.2.3
@@ -1,4 +1,4 @@
-/* $Id: rtl.h,v 1.52.2.2 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: rtl.h,v 1.52.2.3 2004/12/13 16:18:01 hyperion Exp $
*
*/
reactos/include/ntos
diff -u -r1.9.2.2 -r1.9.2.3
--- haltypes.h 13 Dec 2004 09:38:51 -0000 1.9.2.2
+++ haltypes.h 13 Dec 2004 16:18:01 -0000 1.9.2.3
@@ -1,4 +1,4 @@
-/* $Id: haltypes.h,v 1.9.2.2 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: haltypes.h,v 1.9.2.3 2004/12/13 16:18:01 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/include/ntos
diff -u -r1.38.2.2 -r1.38.2.3
--- rtl.h 13 Dec 2004 09:38:51 -0000 1.38.2.2
+++ rtl.h 13 Dec 2004 16:18:01 -0000 1.38.2.3
@@ -1,4 +1,4 @@
-/* $Id: rtl.h,v 1.38.2.2 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: rtl.h,v 1.38.2.3 2004/12/13 16:18:01 hyperion Exp $
*
*/
#ifndef __DDK_RTL_H
reactos/include/ntos
diff -u -r1.35.2.3 -r1.35.2.4
--- zw.h 13 Dec 2004 09:38:51 -0000 1.35.2.3
+++ zw.h 13 Dec 2004 16:18:01 -0000 1.35.2.4
@@ -1,5 +1,5 @@
-/* $Id: zw.h,v 1.35.2.3 2004/12/13 09:38:51 hyperion Exp $
+/* $Id: zw.h,v 1.35.2.4 2004/12/13 16:18:01 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/lib/advapi32
diff -u -r1.25.2.1 -r1.25.2.2
--- advapi32.def 13 Dec 2004 09:38:53 -0000 1.25.2.1
+++ advapi32.def 13 Dec 2004 16:18:02 -0000 1.25.2.2
@@ -1,4 +1,4 @@
-; $Id: advapi32.def,v 1.25.2.1 2004/12/13 09:38:53 hyperion Exp $
+; $Id: advapi32.def,v 1.25.2.2 2004/12/13 16:18:02 hyperion Exp $
;
; advapi32.def
;
reactos/lib/advapi32
diff -u -r1.42.8.1 -r1.42.8.2
--- makefile 13 Dec 2004 09:38:53 -0000 1.42.8.1
+++ makefile 13 Dec 2004 16:18:02 -0000 1.42.8.2
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.42.8.1 2004/12/13 09:38:53 hyperion Exp $
+# $Id: makefile,v 1.42.8.2 2004/12/13 16:18:02 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/advapi32/misc
diff -u -r1.8.8.1 -r1.8.8.2
--- sysfunc.c 13 Dec 2004 09:38:54 -0000 1.8.8.1
+++ sysfunc.c 13 Dec 2004 16:18:02 -0000 1.8.8.2
@@ -1,4 +1,4 @@
-/* $Id: sysfunc.c,v 1.8.8.1 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: sysfunc.c,v 1.8.8.2 2004/12/13 16:18:02 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/advapi32/reg
diff -u -r1.63.2.2 -r1.63.2.3
--- reg.c 13 Dec 2004 09:38:54 -0000 1.63.2.2
+++ reg.c 13 Dec 2004 16:18:02 -0000 1.63.2.3
@@ -1,4 +1,4 @@
-/* $Id: reg.c,v 1.63.2.2 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: reg.c,v 1.63.2.3 2004/12/13 16:18:02 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/advapi32/sec
diff -u -r1.27.2.1 -r1.27.2.2
--- misc.c 13 Dec 2004 09:38:54 -0000 1.27.2.1
+++ misc.c 13 Dec 2004 16:18:02 -0000 1.27.2.2
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.27.2.1 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: misc.c,v 1.27.2.2 2004/12/13 16:18:02 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@@ -8,6 +8,7 @@
#include "advapi32.h"
#include <accctrl.h>
+#include <malloc.h>
#define NDEBUG
#include <debug.h>
@@ -478,31 +479,40 @@
* lpSize [I/O] Size of lpszName.
*
*
- * @unimplemented
+ * @implemented
*/
BOOL WINAPI
GetUserNameA( LPSTR lpszName, LPDWORD lpSize )
{
- size_t len;
- const char* name = "Administrator";
-
- DPRINT1("GetUserNameA: stub\n");
+ WCHAR* lpszNameW = NULL;
+ DWORD len = 0;
+
if ( !lpSize )
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- /* We need to include the null character when determining the size of the buffer. */
- len = strlen(name) + 1;
- if (len > *lpSize)
+
+ len = *lpSize;
+ lpszNameW = LocalAlloc ( LMEM_FIXED, len * sizeof(WCHAR) );
+
+ if ( !GetUserNameW ( lpszNameW, &len ) )
{
- SetLastError(ERROR_MORE_DATA);
- *lpSize = len;
+ LocalFree ( lpszNameW );
return FALSE;
}
-
+
+ len = wcstombs ( lpszName, lpszNameW, len );
+
+ LocalFree ( lpszNameW );
+
+ if ( len > *lpSize )
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+
*lpSize = len;
- strcpy(lpszName, name);
return TRUE;
}
@@ -511,26 +521,108 @@
*
* See GetUserNameA.
*
- * @unimplemented
+ * @implemented
*/
BOOL WINAPI
-GetUserNameW( LPWSTR lpszName, LPDWORD lpSize )
+GetUserNameW ( LPWSTR lpszName, LPDWORD lpSize )
{
-// char name[] = { "Administrator" };
+ HANDLE hToken = INVALID_HANDLE_VALUE;
+ DWORD tu_len = 0;
+ char* tu_buf = NULL;
+ TOKEN_USER* token_user = NULL;
+ DWORD an_len = 0;
+ SID_NAME_USE snu = SidTypeUser;
+ WCHAR* domain_name = NULL;
+ DWORD dn_len = 0;
+
+ if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) )
+ {
+ DWORD dwLastError = GetLastError();
+ if ( dwLastError != ERROR_NO_TOKEN
+ && dwLastError != ERROR_NO_IMPERSONATION_TOKEN )
+ {
+ // don't call SetLastError(),
+ // as OpenThreadToken() ought to have set one
+ return FALSE;
+ }
+ if ( !OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
+ {
+ // don't call SetLastError(),
+ // as OpenProcessToken() ought to have set one
+ return FALSE;
+ }
+ }
+ tu_buf = LocalAlloc ( LMEM_FIXED, 36 );
+ if ( !tu_buf )
+ {
+ SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+ if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, 36, &tu_len ) || tu_len > 36 )
+ {
+ LocalFree ( tu_buf );
+ tu_buf = LocalAlloc ( LMEM_FIXED, tu_len );
+ if ( !tu_buf )
+ {
+ SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+ if ( !GetTokenInformation ( hToken, TokenUser, tu_buf, tu_len, &tu_len ) )
+ {
+ // don't call SetLastError(),
+ // as GetTokenInformation() ought to have set one
+ LocalFree ( tu_buf );
+ CloseHandle ( hToken );
+ return FALSE;
+ }
+ }
+ token_user = (TOKEN_USER*)tu_buf;
-// DWORD len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
+ an_len = *lpSize;
+ dn_len = 32;
+ domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
+ if ( !domain_name )
+ {
+ LocalFree ( tu_buf );
+ SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+ if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu )
+ || dn_len > 32 )
+ {
+ if ( dn_len > 32 )
+ {
+ LocalFree ( domain_name );
+ domain_name = LocalAlloc ( LMEM_FIXED, dn_len * sizeof(WCHAR) );
+ if ( !domain_name )
+ {
+ LocalFree ( tu_buf );
+ SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
+ return FALSE;
+ }
+ }
+ if ( !LookupAccountSidW ( NULL, token_user->User.Sid, lpszName, &an_len, domain_name, &dn_len, &snu ) )
+ {
+ // don't call SetLastError(),
+ // as LookupAccountSid() ought to have set one
+ LocalFree ( domain_name );
+ CloseHandle ( hToken );
+ return FALSE;
+ }
+ }
+
+ LocalFree ( domain_name );
+ LocalFree ( tu_buf );
+ CloseHandle ( hToken );
-// if (len > *lpSize)
-// {
-// SetLastError(ERROR_MORE_DATA);
-// *lpSize = len;
-// return FALSE;
-// }
-
-// *lpSize = len;
-// MultiByteToWideChar( CP_ACP, 0, name, -1, lpszName, len );
- DPRINT1("GetUserNameW: stub\n");
- return TRUE;
+ if ( an_len > *lpSize )
+ {
+ *lpSize = an_len;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+
+ return TRUE;
}
reactos/lib/advapi32/token
diff -u -r1.14.6.1 -r1.14.6.2
--- token.c 13 Dec 2004 09:38:54 -0000 1.14.6.1
+++ token.c 13 Dec 2004 16:18:02 -0000 1.14.6.2
@@ -1,4 +1,4 @@
-/* $Id: token.c,v 1.14.6.1 2004/12/13 09:38:54 hyperion Exp $
+/* $Id: token.c,v 1.14.6.2 2004/12/13 16:18:02 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/cabinet
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template 13 Dec 2004 09:38:54 -0000 1.3.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:02 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:38:54 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:02 hyperion Exp $
TARGET_NAME = cabinet
reactos/lib/comctl32
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template 13 Dec 2004 09:38:55 -0000 1.3.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:02 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:02 hyperion Exp $
TARGET_NAME = comctl32
reactos/lib/cpl/ncpa
diff -u -r1.4.2.1 -r1.4.2.2
--- tcpip_properties.c 13 Dec 2004 09:38:55 -0000 1.4.2.1
+++ tcpip_properties.c 13 Dec 2004 16:18:02 -0000 1.4.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: tcpip_properties.c,v 1.4.2.1 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: tcpip_properties.c,v 1.4.2.2 2004/12/13 16:18:02 hyperion Exp $
*
* PROJECT: ReactOS Network Control Panel
* FILE: lib/cpl/system/tcpip_properties.c
reactos/lib/dinput
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile 13 Dec 2004 09:38:55 -0000 1.2.16.2
+++ Makefile 13 Dec 2004 16:18:02 -0000 1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile,v 1.2.16.3 2004/12/13 16:18:02 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/dnsapi
diff -u -r1.5.16.2 -r1.5.16.3
--- Makefile 13 Dec 2004 09:38:55 -0000 1.5.16.2
+++ Makefile 13 Dec 2004 16:18:03 -0000 1.5.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.5.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile,v 1.5.16.3 2004/12/13 16:18:03 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/expat
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile 13 Dec 2004 09:38:55 -0000 1.3.16.2
+++ Makefile 13 Dec 2004 16:18:03 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile,v 1.3.16.3 2004/12/13 16:18:03 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/freetype/i386
diff -u -r1.1.34.2 -r1.1.34.3
--- setjmplongjmp.s 13 Dec 2004 09:38:55 -0000 1.1.34.2
+++ setjmplongjmp.s 13 Dec 2004 16:18:03 -0000 1.1.34.3
@@ -1,4 +1,4 @@
-/* $Id: setjmplongjmp.s,v 1.1.34.2 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: setjmplongjmp.s,v 1.1.34.3 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: FreeType implementation for ReactOS
reactos/lib/icmp
diff -u -r1.1.6.2 -r1.1.6.3
--- Makefile.ros-template 13 Dec 2004 09:38:55 -0000 1.1.6.2
+++ Makefile.ros-template 13 Dec 2004 16:18:03 -0000 1.1.6.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.6.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.6.3 2004/12/13 16:18:03 hyperion Exp $
TARGET_NAME = icmp
reactos/lib/iphlpapi
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template 13 Dec 2004 09:38:55 -0000 1.2.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:03 -0000 1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:38:55 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:03 hyperion Exp $
TARGET_NAME = iphlpapi
reactos/lib/kernel32/debug
diff -u -r1.4.22.1 -r1.4.22.2
--- debugger.c 13 Dec 2004 09:38:55 -0000 1.4.22.1
+++ debugger.c 13 Dec 2004 16:18:03 -0000 1.4.22.2
@@ -1,4 +1,4 @@
-/* $Id: debugger.c,v 1.4.22.1 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: debugger.c,v 1.4.22.2 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/except
diff -u -r1.18.2.1 -r1.18.2.2
--- except.c 13 Dec 2004 09:38:55 -0000 1.18.2.1
+++ except.c 13 Dec 2004 16:18:03 -0000 1.18.2.2
@@ -1,4 +1,4 @@
-/* $Id: except.c,v 1.18.2.1 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: except.c,v 1.18.2.2 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@@ -88,10 +88,11 @@
LONG STDCALL
UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
+#if 0
DWORD RetValue;
+#endif
HANDLE DebugPort = NULL;
NTSTATUS ErrCode;
- static int RecursionTrap = 3;
#if 0
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION &&
@@ -104,36 +105,23 @@
}
#endif
- if (RecursionTrap > 0)
+ /* Is there a debugger running ? */
+ ErrCode = NtQueryInformationProcess(NtCurrentProcess(), ProcessDebugPort,
+ &DebugPort, sizeof(HANDLE), NULL);
+ if (!NT_SUCCESS(ErrCode) && ErrCode != STATUS_NOT_IMPLEMENTED)
{
- /* Is there a debugger running ? */
- ErrCode = NtQueryInformationProcess(NtCurrentProcess(), ProcessDebugPort,
- &DebugPort, sizeof(HANDLE), NULL);
- if (!NT_SUCCESS(ErrCode) && ErrCode != STATUS_NOT_IMPLEMENTED)
- {
- SetLastErrorByStatus(ErrCode);
- return EXCEPTION_EXECUTE_HANDLER;
- }
-
- if (DebugPort)
- {
- /* Pass the exception to debugger. */
- DPRINT("Passing exception to debugger\n");
- return EXCEPTION_CONTINUE_SEARCH;
- }
+ SetLastErrorByStatus(ErrCode);
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
- /* Run unhandled exception handler. */
- if (GlobalTopLevelExceptionFilter != NULL)
- {
- RetValue = GlobalTopLevelExceptionFilter(ExceptionInfo);
- if (RetValue == EXCEPTION_EXECUTE_HANDLER)
- return EXCEPTION_EXECUTE_HANDLER;
- if (RetValue == EXCEPTION_CONTINUE_EXECUTION)
- return EXCEPTION_CONTINUE_EXECUTION;
- }
+ if (DebugPort)
+ {
+ /* Pass the exception to debugger. */
+ DPRINT("Passing exception to debugger\n");
+ return EXCEPTION_CONTINUE_SEARCH;
}
- if (RecursionTrap-- > 0 && (GetErrorMode() & SEM_NOGPFAULTERRORBOX) == 0)
+ if ((GetErrorMode() & SEM_NOGPFAULTERRORBOX) == 0)
{
#ifdef _X86_
PULONG Frame;
reactos/lib/kernel32/file
diff -u -r1.40.2.2 -r1.40.2.3
--- create.c 13 Dec 2004 09:38:55 -0000 1.40.2.2
+++ create.c 13 Dec 2004 16:18:03 -0000 1.40.2.3
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.40.2.2 2004/12/13 09:38:55 hyperion Exp $
+/* $Id: create.c,v 1.40.2.3 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/file
diff -u -r1.17.8.2 -r1.17.8.3
--- delete.c 13 Dec 2004 09:38:56 -0000 1.17.8.2
+++ delete.c 13 Dec 2004 16:18:03 -0000 1.17.8.3
@@ -1,4 +1,4 @@
-/* $Id: delete.c,v 1.17.8.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: delete.c,v 1.17.8.3 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/file
diff -u -r1.50.2.1 -r1.50.2.2
--- dir.c 13 Dec 2004 09:38:56 -0000 1.50.2.1
+++ dir.c 13 Dec 2004 16:18:03 -0000 1.50.2.2
@@ -1,4 +1,4 @@
-/* $Id: dir.c,v 1.50.2.1 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: dir.c,v 1.50.2.2 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/file
diff -u -r1.60.2.2 -r1.60.2.3
--- file.c 13 Dec 2004 09:38:56 -0000 1.60.2.2
+++ file.c 13 Dec 2004 16:18:03 -0000 1.60.2.3
@@ -1,4 +1,4 @@
-/* $Id: file.c,v 1.60.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: file.c,v 1.60.2.3 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/file
diff -u -r1.15.2.2 -r1.15.2.3
--- iocompl.c 13 Dec 2004 09:38:56 -0000 1.15.2.2
+++ iocompl.c 13 Dec 2004 16:18:03 -0000 1.15.2.3
@@ -1,4 +1,4 @@
-/* $Id: iocompl.c,v 1.15.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: iocompl.c,v 1.15.2.3 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/file
diff -u -r1.14.16.2 -r1.14.16.3
--- move.c 13 Dec 2004 09:38:56 -0000 1.14.16.2
+++ move.c 13 Dec 2004 16:18:03 -0000 1.14.16.3
@@ -1,4 +1,4 @@
-/* $Id: move.c,v 1.14.16.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: move.c,v 1.14.16.3 2004/12/13 16:18:03 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/include
diff -u -r1.6.10.1 -r1.6.10.2
--- kernel32.h 13 Dec 2004 09:38:56 -0000 1.6.10.1
+++ kernel32.h 13 Dec 2004 16:18:03 -0000 1.6.10.2
@@ -43,6 +43,8 @@
extern UNICODE_STRING DllDirectory;
+extern LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter;
+
/* FUNCTION PROTOTYPES *******************************************************/
BOOL STDCALL IsConsoleHandle(HANDLE Handle);
reactos/lib/kernel32
diff -u -r1.89.2.2 -r1.89.2.3
--- makefile 13 Dec 2004 09:38:56 -0000 1.89.2.2
+++ makefile 13 Dec 2004 16:18:03 -0000 1.89.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.89.2.2 2004/12/13 09:38:56 hyperion Exp $
+# $Id: makefile,v 1.89.2.3 2004/12/13 16:18:03 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/kernel32/misc
diff -u -r1.20.16.2 -r1.20.16.3
--- atom.c 13 Dec 2004 09:38:56 -0000 1.20.16.2
+++ atom.c 13 Dec 2004 16:18:04 -0000 1.20.16.3
@@ -1,4 +1,4 @@
-/* $Id: atom.c,v 1.20.16.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: atom.c,v 1.20.16.3 2004/12/13 16:18:04 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/misc
diff -u -r1.37.2.2 -r1.37.2.3
--- dllmain.c 13 Dec 2004 09:38:56 -0000 1.37.2.2
+++ dllmain.c 13 Dec 2004 16:18:04 -0000 1.37.2.3
@@ -1,4 +1,4 @@
-/* $Id: dllmain.c,v 1.37.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: dllmain.c,v 1.37.2.3 2004/12/13 16:18:04 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/misc
diff -u -r1.24.2.2 -r1.24.2.3
--- lang.c 13 Dec 2004 09:38:56 -0000 1.24.2.2
+++ lang.c 13 Dec 2004 16:18:04 -0000 1.24.2.3
@@ -1,4 +1,4 @@
-/* $Id: lang.c,v 1.24.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: lang.c,v 1.24.2.3 2004/12/13 16:18:04 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT : ReactOS user mode libraries
reactos/lib/kernel32/misc
diff -u -r1.94.2.2 -r1.94.2.3
--- stubs.c 13 Dec 2004 09:38:56 -0000 1.94.2.2
+++ stubs.c 13 Dec 2004 16:18:04 -0000 1.94.2.3
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.94.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: stubs.c,v 1.94.2.3 2004/12/13 16:18:04 hyperion Exp $
*
* KERNEL32.DLL stubs (STUB functions)
* Remove from this file, if you implement them.
reactos/lib/kernel32/misc
diff -u -r1.32.2.2 -r1.32.2.3
--- time.c 13 Dec 2004 09:38:56 -0000 1.32.2.2
+++ time.c 13 Dec 2004 16:18:04 -0000 1.32.2.3
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.32.2.2 2004/12/13 09:38:56 hyperion Exp $
+/* $Id: time.c,v 1.32.2.3 2004/12/13 16:18:04 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/process
diff -u -r1.89.2.1 -r1.89.2.2
--- create.c 13 Dec 2004 05:55:32 -0000 1.89.2.1
+++ create.c 13 Dec 2004 16:18:04 -0000 1.89.2.2
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.89.2.1 2004/12/13 05:55:32 hyperion Exp $
+/* $Id: create.c,v 1.89.2.2 2004/12/13 16:18:04 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@@ -12,6 +12,7 @@
/* INCLUDES ****************************************************************/
#include <k32.h>
+#include <pseh/framebased.h>
#define NDEBUG
#include "../include/debug.h"
@@ -291,20 +292,30 @@
{
EXCEPTION_POINTERS ExceptionInfo;
EXCEPTION_DISPOSITION ExceptionDisposition;
+
ExceptionInfo.ExceptionRecord = ExceptionRecord;
ExceptionInfo.ContextRecord = ContextRecord;
- ExceptionDisposition = UnhandledExceptionFilter(&ExceptionInfo);
- if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
+
+ if (GlobalTopLevelExceptionFilter != NULL)
{
- /* FIXME */
-#if 0
- if (_BaseRunningInServerProcess)
- ExitThread(ExceptionRecord->ExceptionCode);
- else
-#endif
- ExitProcess(ExceptionRecord->ExceptionCode);
+ _SEH_TRY
+ {
+ ExceptionDisposition = GlobalTopLevelExceptionFilter(&ExceptionInfo);
+ }
+ _SEH_HANDLE
+ {
+ ExceptionDisposition = UnhandledExceptionFilter(&ExceptionInfo);
+ }
+ _SEH_END;
+ }
+ else
+ {
+ ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
}
+ if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
+ ExitProcess(ExceptionRecord->ExceptionCode);
+
/* translate EXCEPTION_XXX defines into EXCEPTION_DISPOSITION enum values */
if (ExceptionDisposition == EXCEPTION_CONTINUE_EXECUTION)
return ExceptionContinueExecution;
@@ -327,6 +338,8 @@
{
uExitCode = (lpStartAddress)((PVOID)lpParameter);
} __except1
+
+ ExitProcess(uExitCode);
}
reactos/lib/kernel32/synch
diff -u -r1.31.2.2 -r1.31.2.3
--- wait.c 13 Dec 2004 09:38:57 -0000 1.31.2.2
+++ wait.c 13 Dec 2004 16:18:06 -0000 1.31.2.3
@@ -1,4 +1,4 @@
-/* $Id: wait.c,v 1.31.2.2 2004/12/13 09:38:57 hyperion Exp $
+/* $Id: wait.c,v 1.31.2.3 2004/12/13 16:18:06 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/kernel32/thread
diff -u -r1.56.2.2 -r1.56.2.3
--- thread.c 13 Dec 2004 09:38:57 -0000 1.56.2.2
+++ thread.c 13 Dec 2004 16:18:06 -0000 1.56.2.3
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.56.2.2 2004/12/13 09:38:57 hyperion Exp $
+/* $Id: thread.c,v 1.56.2.3 2004/12/13 16:18:06 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
@@ -14,6 +14,7 @@
/* INCLUDES ******************************************************************/
#include <k32.h>
+#include <pseh/framebased.h>
#define NDEBUG
#include "../include/debug.h"
@@ -28,10 +29,39 @@
CONTEXT *ContextRecord,
void * DispatcherContext)
{
- ExitThread(0);
+ EXCEPTION_POINTERS ExceptionInfo;
+ EXCEPTION_DISPOSITION ExceptionDisposition;
- /* We should not get to here */
- return(ExceptionContinueSearch);
+ ExceptionInfo.ExceptionRecord = ExceptionRecord;
+ ExceptionInfo.ContextRecord = ContextRecord;
+
+ if (GlobalTopLevelExceptionFilter != NULL)
+ {
+ _SEH_TRY
+ {
+ ExceptionDisposition = GlobalTopLevelExceptionFilter(&ExceptionInfo);
+ }
+ _SEH_HANDLE
+ {
+ ExceptionDisposition = UnhandledExceptionFilter(&ExceptionInfo);
+ }
+ _SEH_END;
+ }
+ else
+ {
+ ExceptionDisposition = EXCEPTION_EXECUTE_HANDLER;
+ }
+
+ if (ExceptionDisposition == EXCEPTION_EXECUTE_HANDLER)
+ ExitThread(ExceptionRecord->ExceptionCode);
+
+ /* translate EXCEPTION_XXX defines into EXCEPTION_DISPOSITION enum values */
+ if (ExceptionDisposition == EXCEPTION_CONTINUE_EXECUTION)
+ return ExceptionContinueExecution;
+ else if (ExceptionDisposition == EXCEPTION_CONTINUE_SEARCH)
+ return ExceptionContinueSearch;
+
+ return -1; /* unknown return from UnhandledExceptionFilter */
}
@@ -50,8 +80,6 @@
uExitCode = (lpStartAddress)(lpParameter);
}
__except1
- {
- }
ExitThread(uExitCode);
}
reactos/lib/kjs
diff -u -r1.1.24.2 -r1.1.24.3
--- makefile 13 Dec 2004 09:38:57 -0000 1.1.24.2
+++ makefile 13 Dec 2004 16:18:06 -0000 1.1.24.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.1.24.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: makefile,v 1.1.24.3 2004/12/13 16:18:06 hyperion Exp $
# Kernel JavaScript
#
# You can use this for various things but the most obvious is as a powerful
reactos/lib/libwine
diff -u -r1.3.6.2 -r1.3.6.3
--- makefile 13 Dec 2004 09:38:57 -0000 1.3.6.2
+++ makefile 13 Dec 2004 16:18:06 -0000 1.3.6.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.3.6.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: makefile,v 1.3.6.3 2004/12/13 16:18:06 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/midimap
diff -u -r1.1.2.2 -r1.1.2.3
--- Makefile.ros-template 13 Dec 2004 09:38:57 -0000 1.1.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:06 -0000 1.1.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.2.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.2.3 2004/12/13 16:18:06 hyperion Exp $
TARGET_NAME = midimap
reactos/lib/mpr
diff -u -r1.3.2.2 -r1.3.2.3
--- Makefile.ros-template 13 Dec 2004 09:38:57 -0000 1.3.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.3.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.2.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.2.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = mpr
reactos/lib/msacm
diff -u -r1.3.8.2 -r1.3.8.3
--- Makefile.ros-template 13 Dec 2004 09:38:57 -0000 1.3.8.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.3.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.8.2 2004/12/13 09:38:57 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.8.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = msacm32
reactos/lib/msvcrt
diff -u -r1.48.6.2 -r1.48.6.3
--- Makefile 13 Dec 2004 09:38:58 -0000 1.48.6.2
+++ Makefile 13 Dec 2004 16:18:07 -0000 1.48.6.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.48.6.2 2004/12/13 09:38:58 hyperion Exp $
+# $Id: Makefile,v 1.48.6.3 2004/12/13 16:18:07 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/msvcrt/setjmp/i386
diff -u -r1.1.34.2 -r1.1.34.3
--- setjmp.s 13 Dec 2004 09:38:59 -0000 1.1.34.2
+++ setjmp.s 13 Dec 2004 16:18:07 -0000 1.1.34.3
@@ -1,4 +1,4 @@
-/* $Id: setjmp.s,v 1.1.34.2 2004/12/13 09:38:59 hyperion Exp $
+/* $Id: setjmp.s,v 1.1.34.3 2004/12/13 16:18:07 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/msvideo
diff -u -r1.1.8.2 -r1.1.8.3
--- Makefile.ros-template 13 Dec 2004 09:38:59 -0000 1.1.8.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.1.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.8.2 2004/12/13 09:38:59 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.8.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = msvfw32
reactos/lib/netapi32
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template 13 Dec 2004 09:38:59 -0000 1.3.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:38:59 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = netapi32
reactos/lib/ntdll/def
diff -u -r1.134.2.2 -r1.134.2.3
--- ntdll.def 13 Dec 2004 09:39:00 -0000 1.134.2.2
+++ ntdll.def 13 Dec 2004 16:18:07 -0000 1.134.2.3
@@ -1,4 +1,4 @@
-; $Id: ntdll.def,v 1.134.2.2 2004/12/13 09:39:00 hyperion Exp $
+; $Id: ntdll.def,v 1.134.2.3 2004/12/13 16:18:07 hyperion Exp $
;
; ReactOS Operating System
;
reactos/lib/ntdll/rtl
diff -u -r1.29.8.2 -r1.29.8.3
--- path.c 13 Dec 2004 09:39:00 -0000 1.29.8.2
+++ path.c 13 Dec 2004 16:18:07 -0000 1.29.8.3
@@ -1,4 +1,4 @@
-/* $Id: path.c,v 1.29.8.2 2004/12/13 09:39:00 hyperion Exp $
+/* $Id: path.c,v 1.29.8.3 2004/12/13 16:18:07 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/odbc32
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:00 -0000 1.2.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:00 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = odbc32
reactos/lib/ole32
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:00 -0000 1.2.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:00 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = ole32
reactos/lib/oleaut32
diff -u -r1.5.2.2 -r1.5.2.3
--- Makefile.ros-template 13 Dec 2004 09:39:00 -0000 1.5.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.5.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.5.2.2 2004/12/13 09:39:00 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.5.2.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = oleaut32
reactos/lib/oledlg
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.3.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:07 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:07 hyperion Exp $
TARGET_NAME = oledlg
reactos/lib/olepro32
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.2.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = olepro32
reactos/lib/riched20
diff -u -r1.1.2.2 -r1.1.2.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.1.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.1.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.1.2.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.1.2.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = riched20
reactos/lib/richedit
diff -u -r1.2.16.2 -r1.2.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.2.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.2.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.16.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = riched32
reactos/lib/rpcrt4
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.3.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = rpcrt4
reactos/lib/rtl
diff -u -r1.4.2.2 -r1.4.2.3
--- acl.c 13 Dec 2004 09:39:01 -0000 1.4.2.2
+++ acl.c 13 Dec 2004 16:18:08 -0000 1.4.2.3
@@ -1,4 +1,4 @@
-/* $Id: acl.c,v 1.4.2.2 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: acl.c,v 1.4.2.3 2004/12/13 16:18:08 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/lib/rtl
diff -u -r1.1.18.1 -r1.1.18.2
--- largeint.c 13 Dec 2004 09:39:01 -0000 1.1.18.1
+++ largeint.c 13 Dec 2004 16:18:08 -0000 1.1.18.2
@@ -1,4 +1,4 @@
-/* $Id: largeint.c,v 1.1.18.1 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: largeint.c,v 1.1.18.2 2004/12/13 16:18:08 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/lib/rtl
diff -u -r1.2.8.2 -r1.2.8.3
--- mem.c 13 Dec 2004 09:39:01 -0000 1.2.8.2
+++ mem.c 13 Dec 2004 16:18:08 -0000 1.2.8.3
@@ -1,5 +1,5 @@
-/* $Id: mem.c,v 1.2.8.2 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: mem.c,v 1.2.8.3 2004/12/13 16:18:08 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/lib/rtl
diff -u -r1.1.18.2 -r1.1.18.3
--- nls.c 13 Dec 2004 09:39:01 -0000 1.1.18.2
+++ nls.c 13 Dec 2004 16:18:08 -0000 1.1.18.3
@@ -1,4 +1,4 @@
-/* $Id: nls.c,v 1.1.18.2 2004/12/13 09:39:01 hyperion Exp $
+/* $Id: nls.c,v 1.1.18.3 2004/12/13 16:18:08 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/lib/setupapi
diff -u -r1.4.16.2 -r1.4.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.4.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.4.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.4.16.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.4.16.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = setupapi
reactos/lib/shell32
diff -u -r1.6.2.2 -r1.6.2.3
--- Makefile.ros-template 13 Dec 2004 09:39:01 -0000 1.6.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.6.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.6.2.2 2004/12/13 09:39:01 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.6.2.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = shell32
reactos/lib/shlwapi
diff -u -r1.9.2.2 -r1.9.2.3
--- Makefile.ros-template 13 Dec 2004 09:39:02 -0000 1.9.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.9.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.9.2.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.9.2.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = shlwapi
reactos/lib/string
diff -u -r1.2.34.2 -r1.2.34.3
--- strncpy.c 13 Dec 2004 09:39:02 -0000 1.2.34.2
+++ strncpy.c 13 Dec 2004 16:18:08 -0000 1.2.34.3
@@ -1,4 +1,4 @@
-/* $Id: strncpy.c,v 1.2.34.2 2004/12/13 09:39:02 hyperion Exp $
+/* $Id: strncpy.c,v 1.2.34.3 2004/12/13 16:18:08 hyperion Exp $
*/
#include <string.h>
#include "tcsncpy.h"
reactos/lib/syssetup
diff -u -r1.8.2.2 -r1.8.2.3
--- syssetup.rc 13 Dec 2004 09:39:02 -0000 1.8.2.2
+++ syssetup.rc 13 Dec 2004 16:18:08 -0000 1.8.2.3
@@ -1,4 +1,4 @@
-/* $Id: syssetup.rc,v 1.8.2.2 2004/12/13 09:39:02 hyperion Exp $ */
+/* $Id: syssetup.rc,v 1.8.2.3 2004/12/13 16:18:08 hyperion Exp $ */
#include <windows.h>
#include "resource.h"
reactos/lib/syssetup
diff -u -r1.15.2.2 -r1.15.2.3
--- wizard.c 13 Dec 2004 09:39:02 -0000 1.15.2.2
+++ wizard.c 13 Dec 2004 16:18:08 -0000 1.15.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: wizard.c,v 1.15.2.2 2004/12/13 09:39:02 hyperion Exp $
+/* $Id: wizard.c,v 1.15.2.3 2004/12/13 16:18:08 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/twain
diff -u -r1.7.16.2 -r1.7.16.3
--- Makefile 13 Dec 2004 09:39:02 -0000 1.7.16.2
+++ Makefile 13 Dec 2004 16:18:08 -0000 1.7.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7.16.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile,v 1.7.16.3 2004/12/13 16:18:08 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/unicode
diff -u -r1.3.2.2 -r1.3.2.3
--- Makefile.ros-template 13 Dec 2004 09:39:02 -0000 1.3.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:08 -0000 1.3.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.2.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.2.3 2004/12/13 16:18:08 hyperion Exp $
TARGET_NAME = wine_unicode
reactos/lib/urlmon
diff -u -r1.2.8.2 -r1.2.8.3
--- Makefile.ros-template 13 Dec 2004 09:39:02 -0000 1.2.8.2
+++ Makefile.ros-template 13 Dec 2004 16:18:09 -0000 1.2.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.8.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.8.3 2004/12/13 16:18:09 hyperion Exp $
TARGET_NAME = urlmon
reactos/lib/user32
diff -u -r1.40.8.2 -r1.40.8.3
--- Makefile 13 Dec 2004 09:39:02 -0000 1.40.8.2
+++ Makefile 13 Dec 2004 16:18:09 -0000 1.40.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.40.8.2 2004/12/13 09:39:02 hyperion Exp $
+# $Id: Makefile,v 1.40.8.3 2004/12/13 16:18:09 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/user32/misc
diff -u -r1.13.2.1 -r1.13.2.2
--- display.c 13 Dec 2004 09:39:02 -0000 1.13.2.1
+++ display.c 13 Dec 2004 16:18:09 -0000 1.13.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: display.c,v 1.13.2.1 2004/12/13 09:39:02 hyperion Exp $
+/* $Id: display.c,v 1.13.2.2 2004/12/13 16:18:09 hyperion Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/misc/dde.c
reactos/lib/user32/misc
diff -u -r1.9.2.2 -r1.9.2.3
--- misc.c 13 Dec 2004 09:39:05 -0000 1.9.2.2
+++ misc.c 13 Dec 2004 16:18:09 -0000 1.9.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: misc.c,v 1.9.2.2 2004/12/13 09:39:05 hyperion Exp $
+/* $Id: misc.c,v 1.9.2.3 2004/12/13 16:18:09 hyperion Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/misc/misc.c
reactos/lib/user32/misc
diff -u -r1.68.2.1 -r1.68.2.2
--- stubs.c 13 Dec 2004 09:39:05 -0000 1.68.2.1
+++ stubs.c 13 Dec 2004 16:18:09 -0000 1.68.2.2
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.68.2.1 2004/12/13 09:39:05 hyperion Exp $
+/* $Id: stubs.c,v 1.68.2.2 2004/12/13 16:18:09 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
reactos/lib/user32/windows
diff -u -r1.51.8.2 -r1.51.8.3
--- class.c 13 Dec 2004 09:39:06 -0000 1.51.8.2
+++ class.c 13 Dec 2004 16:18:09 -0000 1.51.8.3
@@ -1,4 +1,4 @@
-/* $Id: class.c,v 1.51.8.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: class.c,v 1.51.8.3 2004/12/13 16:18:09 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
reactos/lib/user32/windows
diff -u -r1.147.2.1 -r1.147.2.2
--- defwnd.c 13 Dec 2004 09:39:06 -0000 1.147.2.1
+++ defwnd.c 13 Dec 2004 16:18:09 -0000 1.147.2.2
@@ -1,4 +1,4 @@
-/* $Id: defwnd.c,v 1.147.2.1 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: defwnd.c,v 1.147.2.2 2004/12/13 16:18:09 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
reactos/lib/user32/windows
diff -u -r1.11.8.2 -r1.11.8.3
--- font.c 13 Dec 2004 09:39:06 -0000 1.11.8.2
+++ font.c 13 Dec 2004 16:18:10 -0000 1.11.8.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: font.c,v 1.11.8.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: font.c,v 1.11.8.3 2004/12/13 16:18:10 hyperion Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c
reactos/lib/user32/windows
diff -u -r1.25.8.1 -r1.25.8.2
--- input.c 13 Dec 2004 09:39:06 -0000 1.25.8.1
+++ input.c 13 Dec 2004 16:18:10 -0000 1.25.8.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: input.c,v 1.25.8.1 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: input.c,v 1.25.8.2 2004/12/13 16:18:10 hyperion Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c
reactos/lib/user32/windows
diff -u -r1.71.6.2 -r1.71.6.3
--- menu.c 13 Dec 2004 09:39:06 -0000 1.71.6.2
+++ menu.c 13 Dec 2004 16:18:10 -0000 1.71.6.3
@@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: menu.c,v 1.71.6.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: menu.c,v 1.71.6.3 2004/12/13 16:18:10 hyperion Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/menu.c
reactos/lib/user32/windows
diff -u -r1.43.6.2 -r1.43.6.3
--- message.c 13 Dec 2004 09:39:06 -0000 1.43.6.2
+++ message.c 13 Dec 2004 16:18:11 -0000 1.43.6.3
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.43.6.2 2004/12/13 09:39:06 hyperion Exp $
+/* $Id: message.c,v 1.43.6.3 2004/12/13 16:18:11 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS user32.dll
reactos/lib/user32/windows
diff -u -r1.29.2.1 -r1.29.2.2
--- messagebox.c 13 Dec 2004 09:39:07 -0000 1.29.2.1
+++ messagebox.c 13 Dec 2004 16:18:11 -0000 1.29.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: messagebox.c,v 1.29.2.1 2004/12/13 09:39:07 hyperion Exp $
+/* $Id: messagebox.c,v 1.29.2.2 2004/12/13 16:18:11 hyperion Exp $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/messagebox.c
reactos/lib/userenv
diff -u -r1.8.2.2 -r1.8.2.3
--- environment.c 13 Dec 2004 09:39:07 -0000 1.8.2.2
+++ environment.c 13 Dec 2004 16:18:11 -0000 1.8.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: environment.c,v 1.8.2.2 2004/12/13 09:39:07 hyperion Exp $
+/* $Id: environment.c,v 1.8.2.3 2004/12/13 16:18:11 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/lib/version
diff -u -r1.15.16.2 -r1.15.16.3
--- makefile 13 Dec 2004 09:39:07 -0000 1.15.16.2
+++ makefile 13 Dec 2004 16:18:11 -0000 1.15.16.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.15.16.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: makefile,v 1.15.16.3 2004/12/13 16:18:11 hyperion Exp $
PATH_TO_TOP = ../..
reactos/lib/winmm
diff -u -r1.3.16.2 -r1.3.16.3
--- Makefile.ros-template 13 Dec 2004 09:39:07 -0000 1.3.16.2
+++ Makefile.ros-template 13 Dec 2004 16:18:11 -0000 1.3.16.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.16.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.16.3 2004/12/13 16:18:11 hyperion Exp $
TARGET_NAME = winmm
reactos/lib/winmm/midimap
diff -u -r1.3.2.2 -r1.3.2.3
--- Makefile.ros-template 13 Dec 2004 09:39:07 -0000 1.3.2.2
+++ Makefile.ros-template 13 Dec 2004 16:18:11 -0000 1.3.2.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.3.2.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.3.2.3 2004/12/13 16:18:11 hyperion Exp $
TARGET_NAME = midimap
reactos/lib/winmm/wavemap
diff -u -r1.2.8.2 -r1.2.8.3
--- Makefile.ros-template 13 Dec 2004 09:39:07 -0000 1.2.8.2
+++ Makefile.ros-template 13 Dec 2004 16:18:11 -0000 1.2.8.3
@@ -1,4 +1,4 @@
-# $Id: Makefile.ros-template,v 1.2.8.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: Makefile.ros-template,v 1.2.8.3 2004/12/13 16:18:11 hyperion Exp $
TARGET_NAME = msacm
reactos/lib/ws2_32
diff -u -r1.18.2.2 -r1.18.2.3
--- makefile 13 Dec 2004 09:39:07 -0000 1.18.2.2
+++ makefile 13 Dec 2004 16:18:11 -0000 1.18.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.18.2.2 2004/12/13 09:39:07 hyperion Exp $
+# $Id: makefile,v 1.18.2.3 2004/12/13 16:18:11 hyperion Exp $
PATH_TO_TOP = ../..
reactos/ntoskrnl/cm
diff -u -r1.30.8.1 -r1.30.8.2
--- import.c 13 Dec 2004 09:39:08 -0000 1.30.8.1
+++ import.c 13 Dec 2004 16:18:11 -0000 1.30.8.2
@@ -1,4 +1,4 @@
-/* $Id: import.c,v 1.30.8.1 2004/12/13 09:39:08 hyperion Exp $
+/* $Id: import.c,v 1.30.8.2 2004/12/13 16:18:11 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/cm
diff -u -r1.128.2.1 -r1.128.2.2
--- registry.c 13 Dec 2004 09:39:09 -0000 1.128.2.1
+++ registry.c 13 Dec 2004 16:18:11 -0000 1.128.2.2
@@ -1,4 +1,4 @@
-/* $Id: registry.c,v 1.128.2.1 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: registry.c,v 1.128.2.2 2004/12/13 16:18:11 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/dbg
diff -u -r1.20.8.1 -r1.20.8.2
--- print.c 13 Dec 2004 09:39:09 -0000 1.20.8.1
+++ print.c 13 Dec 2004 16:18:12 -0000 1.20.8.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: print.c,v 1.20.8.1 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: print.c,v 1.20.8.2 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ex/i386
diff -u -r1.9.6.1 -r1.9.6.2
--- interlck.c 13 Dec 2004 09:39:09 -0000 1.9.6.1
+++ interlck.c 13 Dec 2004 16:18:12 -0000 1.9.6.2
@@ -1,4 +1,4 @@
-/* $Id: interlck.c,v 1.9.6.1 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: interlck.c,v 1.9.6.2 2004/12/13 16:18:12 hyperion Exp $
*
* reactos/ntoskrnl/ex/i386/interlck.c
*
reactos/ntoskrnl/ex
diff -u -r1.59.2.3 -r1.59.2.4
--- sysinfo.c 13 Dec 2004 09:39:09 -0000 1.59.2.3
+++ sysinfo.c 13 Dec 2004 16:18:12 -0000 1.59.2.4
@@ -1,4 +1,4 @@
-/* $Id: sysinfo.c,v 1.59.2.3 2004/12/13 09:39:09 hyperion Exp $
+/* $Id: sysinfo.c,v 1.59.2.4 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ex
diff -u -r1.24.2.3 -r1.24.2.4
--- time.c 13 Dec 2004 09:39:10 -0000 1.24.2.3
+++ time.c 13 Dec 2004 16:18:12 -0000 1.24.2.4
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.24.2.3 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: time.c,v 1.24.2.4 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/include/internal
diff -u -r1.49.2.2 -r1.49.2.3
--- io.h 13 Dec 2004 09:39:10 -0000 1.49.2.2
+++ io.h 13 Dec 2004 16:18:12 -0000 1.49.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: io.h,v 1.49.2.2 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: io.h,v 1.49.2.3 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/include/internal
diff -u -r1.28.2.1 -r1.28.2.2
--- kd.h 13 Dec 2004 09:39:10 -0000 1.28.2.1
+++ kd.h 13 Dec 2004 16:18:12 -0000 1.28.2.2
@@ -1,4 +1,4 @@
-/* $Id: kd.h,v 1.28.2.1 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: kd.h,v 1.28.2.2 2004/12/13 16:18:12 hyperion Exp $
*
* kernel debugger prototypes
*/
reactos/ntoskrnl/include/internal
diff -u -r1.75.2.2 -r1.75.2.3
--- ps.h 13 Dec 2004 09:39:10 -0000 1.75.2.2
+++ ps.h 13 Dec 2004 16:18:12 -0000 1.75.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: ps.h,v 1.75.2.2 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: ps.h,v 1.75.2.3 2004/12/13 16:18:12 hyperion Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions
reactos/ntoskrnl/io
diff -u -r1.5.6.1 -r1.5.6.2
--- bootlog.c 13 Dec 2004 09:39:10 -0000 1.5.6.1
+++ bootlog.c 13 Dec 2004 16:18:12 -0000 1.5.6.2
@@ -1,4 +1,4 @@
-/* $Id: bootlog.c,v 1.5.6.1 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: bootlog.c,v 1.5.6.2 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/io
diff -u -r1.55.2.1 -r1.55.2.2
--- driver.c 13 Dec 2004 09:39:10 -0000 1.55.2.1
+++ driver.c 13 Dec 2004 16:18:12 -0000 1.55.2.2
@@ -1,4 +1,4 @@
-/* $Id: driver.c,v 1.55.2.1 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: driver.c,v 1.55.2.2 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/io
diff -u -r1.8.8.2 -r1.8.8.3
--- parttab.c 13 Dec 2004 09:39:10 -0000 1.8.8.2
+++ parttab.c 13 Dec 2004 16:18:12 -0000 1.8.8.3
@@ -1,4 +1,4 @@
-/* $Id: parttab.c,v 1.8.8.2 2004/12/13 09:39:10 hyperion Exp $
+/* $Id: parttab.c,v 1.8.8.3 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/kd
diff -u -r1.56.2.1 -r1.56.2.2
--- kdebug.c 13 Dec 2004 09:39:11 -0000 1.56.2.1
+++ kdebug.c 13 Dec 2004 16:18:12 -0000 1.56.2.2
@@ -1,4 +1,4 @@
-/* $Id: kdebug.c,v 1.56.2.1 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: kdebug.c,v 1.56.2.2 2004/12/13 16:18:12 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ke
diff -u -r1.47.2.1 -r1.47.2.2
--- bug.c 13 Dec 2004 09:39:11 -0000 1.47.2.1
+++ bug.c 13 Dec 2004 16:18:13 -0000 1.47.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: bug.c,v 1.47.2.1 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: bug.c,v 1.47.2.2 2004/12/13 16:18:13 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
reactos/ntoskrnl/ke
diff -u -r1.48.2.2 -r1.48.2.3
--- dpc.c 13 Dec 2004 09:39:11 -0000 1.48.2.2
+++ dpc.c 13 Dec 2004 16:18:13 -0000 1.48.2.3
@@ -19,7 +19,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dpc.c,v 1.48.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: dpc.c,v 1.48.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ke
diff -u -r1.3.2.2 -r1.3.2.3
--- ipi.c 13 Dec 2004 09:39:11 -0000 1.3.2.2
+++ ipi.c 13 Dec 2004 16:18:13 -0000 1.3.2.3
@@ -1,4 +1,4 @@
-/* $Id: ipi.c,v 1.3.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: ipi.c,v 1.3.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ke
diff -u -r1.58.2.1 -r1.58.2.2
--- kthread.c 13 Dec 2004 09:39:11 -0000 1.58.2.1
+++ kthread.c 13 Dec 2004 16:18:13 -0000 1.58.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: kthread.c,v 1.58.2.1 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: kthread.c,v 1.58.2.2 2004/12/13 16:18:13 hyperion Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
reactos/ntoskrnl/ke
diff -u -r1.206.2.2 -r1.206.2.3
--- main.c 13 Dec 2004 09:39:11 -0000 1.206.2.2
+++ main.c 13 Dec 2004 16:18:13 -0000 1.206.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: main.c,v 1.206.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: main.c,v 1.206.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
reactos/ntoskrnl/ke
diff -u -r1.31.2.2 -r1.31.2.3
--- process.c 13 Dec 2004 09:39:11 -0000 1.31.2.2
+++ process.c 13 Dec 2004 16:18:13 -0000 1.31.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: process.c,v 1.31.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: process.c,v 1.31.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/process.c
reactos/ntoskrnl/ke
diff -u -r1.90.2.2 -r1.90.2.3
--- timer.c 13 Dec 2004 09:39:11 -0000 1.90.2.2
+++ timer.c 13 Dec 2004 16:18:13 -0000 1.90.2.3
@@ -1,4 +1,4 @@
-/* $Id: timer.c,v 1.90.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: timer.c,v 1.90.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ke/i386
diff -u -r1.17.2.2 -r1.17.2.3
--- fpu.c 13 Dec 2004 09:39:11 -0000 1.17.2.2
+++ fpu.c 13 Dec 2004 16:18:13 -0000 1.17.2.3
@@ -1,4 +1,4 @@
-/* $Id: fpu.c,v 1.17.2.2 2004/12/13 09:39:11 hyperion Exp $
+/* $Id: fpu.c,v 1.17.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
reactos/ntoskrnl/ke/i386
diff -u -r1.55.2.2 -r1.55.2.3
--- irq.c 13 Dec 2004 09:39:12 -0000 1.55.2.2
+++ irq.c 13 Dec 2004 16:18:13 -0000 1.55.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: irq.c,v 1.55.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: irq.c,v 1.55.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/irq.c
reactos/ntoskrnl/ldr
diff -u -r1.49.2.2 -r1.49.2.3
--- init.c 13 Dec 2004 09:39:12 -0000 1.49.2.2
+++ init.c 13 Dec 2004 16:18:13 -0000 1.49.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: init.c,v 1.49.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: init.c,v 1.49.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/init.c
reactos/ntoskrnl/mm/i386
diff -u -r1.77.2.2 -r1.77.2.3
--- page.c 13 Dec 2004 09:39:12 -0000 1.77.2.2
+++ page.c 13 Dec 2004 16:18:13 -0000 1.77.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: page.c,v 1.77.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: page.c,v 1.77.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c
reactos/ntoskrnl/mm
diff -u -r1.92.2.2 -r1.92.2.3
--- npool.c 13 Dec 2004 09:39:12 -0000 1.92.2.2
+++ npool.c 13 Dec 2004 16:18:13 -0000 1.92.2.3
@@ -1,4 +1,4 @@
-/* $Id: npool.c,v 1.92.2.2 2004/12/13 09:39:12 hyperion Exp $
+/* $Id: npool.c,v 1.92.2.3 2004/12/13 16:18:13 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/mm
diff -u -r1.35.6.1 -r1.35.6.2
--- pool.c 13 Dec 2004 09:39:14 -0000 1.35.6.1
+++ pool.c 13 Dec 2004 16:18:14 -0000 1.35.6.2
@@ -1,4 +1,4 @@
-/* $Id: pool.c,v 1.35.6.1 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: pool.c,v 1.35.6.2 2004/12/13 16:18:14 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/mm
diff -u -r1.33.2.1 -r1.33.2.2
--- ppool.c 13 Dec 2004 09:39:14 -0000 1.33.2.1
+++ ppool.c 13 Dec 2004 16:18:14 -0000 1.33.2.2
@@ -1,4 +1,4 @@
-/* $Id: ppool.c,v 1.33.2.1 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: ppool.c,v 1.33.2.2 2004/12/13 16:18:14 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl
diff -u -r1.201.2.2 -r1.201.2.3
--- ntoskrnl.def 13 Dec 2004 09:39:08 -0000 1.201.2.2
+++ ntoskrnl.def 13 Dec 2004 16:18:14 -0000 1.201.2.3
@@ -1,4 +1,4 @@
-; $Id: ntoskrnl.def,v 1.201.2.2 2004/12/13 09:39:08 hyperion Exp $
+; $Id: ntoskrnl.def,v 1.201.2.3 2004/12/13 16:18:14 hyperion Exp $
;
; reactos/ntoskrnl/ntoskrnl.def
;
reactos/ntoskrnl/ps
diff -u -r1.2.2.2 -r1.2.2.3
--- cid.c 13 Dec 2004 09:39:14 -0000 1.2.2.2
+++ cid.c 13 Dec 2004 16:18:14 -0000 1.2.2.3
@@ -1,4 +1,4 @@
-/* $Id: cid.c,v 1.2.2.2 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: cid.c,v 1.2.2.3 2004/12/13 16:18:14 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ps
diff -u -r1.86.2.1 -r1.86.2.2
--- create.c 13 Dec 2004 09:39:14 -0000 1.86.2.1
+++ create.c 13 Dec 2004 16:18:14 -0000 1.86.2.2
@@ -1,4 +1,4 @@
-/* $Id: create.c,v 1.86.2.1 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: create.c,v 1.86.2.2 2004/12/13 16:18:14 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ps
diff -u -r1.86.2.2 -r1.86.2.3
--- kill.c 13 Dec 2004 09:39:14 -0000 1.86.2.2
+++ kill.c 13 Dec 2004 16:18:15 -0000 1.86.2.3
@@ -1,4 +1,4 @@
-/* $Id: kill.c,v 1.86.2.2 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: kill.c,v 1.86.2.3 2004/12/13 16:18:15 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ps
diff -u -r1.157.2.2 -r1.157.2.3
--- process.c 13 Dec 2004 09:39:14 -0000 1.157.2.2
+++ process.c 13 Dec 2004 16:18:16 -0000 1.157.2.3
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.157.2.2 2004/12/13 09:39:14 hyperion Exp $
+/* $Id: process.c,v 1.157.2.3 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ps
diff -u -r1.138.2.2 -r1.138.2.3
--- thread.c 13 Dec 2004 09:39:15 -0000 1.138.2.2
+++ thread.c 13 Dec 2004 16:18:16 -0000 1.138.2.3
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.138.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: thread.c,v 1.138.2.3 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/ps
diff -u -r1.18.2.2 -r1.18.2.3
--- w32call.c 13 Dec 2004 09:39:15 -0000 1.18.2.2
+++ w32call.c 13 Dec 2004 16:18:16 -0000 1.18.2.3
@@ -1,4 +1,4 @@
-/* $Id: w32call.c,v 1.18.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: w32call.c,v 1.18.2.3 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/se
diff -u -r1.21.2.1 -r1.21.2.2
--- acl.c 13 Dec 2004 09:39:15 -0000 1.21.2.1
+++ acl.c 13 Dec 2004 16:18:16 -0000 1.21.2.2
@@ -1,4 +1,4 @@
-/* $Id: acl.c,v 1.21.2.1 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: acl.c,v 1.21.2.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/ntoskrnl/se
diff -u -r1.42.2.1 -r1.42.2.2
--- token.c 13 Dec 2004 09:39:15 -0000 1.42.2.1
+++ token.c 13 Dec 2004 16:18:16 -0000 1.42.2.2
@@ -1,4 +1,4 @@
-/* $Id: token.c,v 1.42.2.1 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: token.c,v 1.42.2.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/csrss/win32csr
diff -u -r1.11.2.2 -r1.11.2.3
--- desktopbg.c 13 Dec 2004 09:39:15 -0000 1.11.2.2
+++ desktopbg.c 13 Dec 2004 16:18:16 -0000 1.11.2.3
@@ -1,4 +1,4 @@
-/* $Id: desktopbg.c,v 1.11.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: desktopbg.c,v 1.11.2.3 2004/12/13 16:18:16 hyperion Exp $
*
* reactos/subsys/csrss/win32csr/desktopbg.c
*
reactos/subsys/csrss/win32csr
diff -u -r1.22.2.2 -r1.22.2.3
--- guiconsole.c 13 Dec 2004 09:39:15 -0000 1.22.2.2
+++ guiconsole.c 13 Dec 2004 16:18:16 -0000 1.22.2.3
@@ -1,4 +1,4 @@
-/* $Id: guiconsole.c,v 1.22.2.2 2004/12/13 09:39:15 hyperion Exp $
+/* $Id: guiconsole.c,v 1.22.2.3 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
reactos/subsys/system/winlogon
diff -u -r1.4.8.2 -r1.4.8.3
--- winlogon.h 13 Dec 2004 09:39:16 -0000 1.4.8.2
+++ winlogon.h 13 Dec 2004 16:18:16 -0000 1.4.8.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: winlogon.h,v 1.4.8.2 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: winlogon.h,v 1.4.8.3 2004/12/13 16:18:16 hyperion Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS winlogon
* FILE: subsys/system/winlogon/winlogon.h
reactos/subsys/win32k/eng
diff -u -r1.58.10.1 -r1.58.10.2
--- bitblt.c 13 Dec 2004 09:39:16 -0000 1.58.10.1
+++ bitblt.c 13 Dec 2004 16:18:16 -0000 1.58.10.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: bitblt.c,v 1.58.10.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: bitblt.c,v 1.58.10.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/eng
diff -u -r1.22.18.1 -r1.22.18.2
--- clip.c 13 Dec 2004 09:39:16 -0000 1.22.18.1
+++ clip.c 13 Dec 2004 16:18:16 -0000 1.22.18.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: clip.c,v 1.22.18.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: clip.c,v 1.22.18.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/eng
diff -u -r1.11.2.1 -r1.11.2.2
--- gradient.c 13 Dec 2004 09:39:16 -0000 1.11.2.1
+++ gradient.c 13 Dec 2004 16:18:16 -0000 1.11.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: gradient.c,v 1.11.2.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: gradient.c,v 1.11.2.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/eng
diff -u -r1.77.8.1 -r1.77.8.2
--- mouse.c 13 Dec 2004 09:39:16 -0000 1.77.8.1
+++ mouse.c 13 Dec 2004 16:18:16 -0000 1.77.8.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: mouse.c,v 1.77.8.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: mouse.c,v 1.77.8.2 2004/12/13 16:18:16 hyperion Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
reactos/subsys/win32k/eng
diff -u -r1.32.12.1 -r1.32.12.2
--- objects.h 13 Dec 2004 09:39:16 -0000 1.32.12.1
+++ objects.h 13 Dec 2004 16:18:16 -0000 1.32.12.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: objects.h,v 1.32.12.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: objects.h,v 1.32.12.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/eng
diff -u -r1.44.12.1 -r1.44.12.2
--- surface.c 13 Dec 2004 09:39:16 -0000 1.44.12.1
+++ surface.c 13 Dec 2004 16:18:16 -0000 1.44.12.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: surface.c,v 1.44.12.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: surface.c,v 1.44.12.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/eng
diff -u -r1.42.8.1 -r1.42.8.2
--- xlate.c 13 Dec 2004 09:39:16 -0000 1.42.8.1
+++ xlate.c 13 Dec 2004 16:18:16 -0000 1.42.8.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: xlate.c,v 1.42.8.1 2004/12/13 09:39:16 hyperion Exp $
+/* $Id: xlate.c,v 1.42.8.2 2004/12/13 16:18:16 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/main
diff -u -r1.82.2.1 -r1.82.2.2
--- dllmain.c 13 Dec 2004 09:39:17 -0000 1.82.2.1
+++ dllmain.c 13 Dec 2004 16:18:17 -0000 1.82.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dllmain.c,v 1.82.2.1 2004/12/13 09:39:17 hyperion Exp $
+/* $Id: dllmain.c,v 1.82.2.2 2004/12/13 16:18:17 hyperion Exp $
*
* Entry Point for win32k.sys
*/
reactos/subsys/win32k
diff -u -r1.105.2.2 -r1.105.2.3
--- makefile 13 Dec 2004 09:39:18 -0000 1.105.2.2
+++ makefile 13 Dec 2004 16:18:17 -0000 1.105.2.3
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.105.2.2 2004/12/13 09:39:18 hyperion Exp $
+# $Id: makefile,v 1.105.2.3 2004/12/13 16:18:17 hyperion Exp $
PATH_TO_TOP = ../..
reactos/subsys/win32k/misc
diff -u -r1.12.16.1 -r1.12.16.2
--- object.c 13 Dec 2004 09:39:19 -0000 1.12.16.1
+++ object.c 13 Dec 2004 16:18:17 -0000 1.12.16.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: object.c,v 1.12.16.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: object.c,v 1.12.16.2 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.60.2.1 -r1.60.2.2
--- class.c 13 Dec 2004 09:39:19 -0000 1.60.2.1
+++ class.c 13 Dec 2004 16:18:17 -0000 1.60.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: class.c,v 1.60.2.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: class.c,v 1.60.2.2 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.24.2.2 -r1.24.2.3
--- desktop.c 13 Dec 2004 09:39:19 -0000 1.24.2.2
+++ desktop.c 13 Dec 2004 16:18:17 -0000 1.24.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: desktop.c,v 1.24.2.2 2004/12/13 09:39:19 hyperion Exp $
+ * $Id: desktop.c,v 1.24.2.3 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.25.2.2 -r1.25.2.3
--- focus.c 13 Dec 2004 09:39:19 -0000 1.25.2.2
+++ focus.c 13 Dec 2004 16:18:17 -0000 1.25.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: focus.c,v 1.25.2.2 2004/12/13 09:39:19 hyperion Exp $
+ * $Id: focus.c,v 1.25.2.3 2004/12/13 16:18:17 hyperion Exp $
*/
#include <w32k.h>
reactos/subsys/win32k/ntuser
diff -u -r1.38.6.1 -r1.38.6.2
--- input.c 13 Dec 2004 09:39:19 -0000 1.38.6.1
+++ input.c 13 Dec 2004 16:18:17 -0000 1.38.6.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: input.c,v 1.38.6.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: input.c,v 1.38.6.2 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.75.2.1 -r1.75.2.2
--- message.c 13 Dec 2004 09:39:19 -0000 1.75.2.1
+++ message.c 13 Dec 2004 16:18:17 -0000 1.75.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: message.c,v 1.75.2.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: message.c,v 1.75.2.2 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.88.2.2 -r1.88.2.3
--- misc.c 13 Dec 2004 09:39:19 -0000 1.88.2.2
+++ misc.c 13 Dec 2004 16:18:17 -0000 1.88.2.3
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.88.2.2 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: misc.c,v 1.88.2.3 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.108.2.1 -r1.108.2.2
--- msgqueue.c 13 Dec 2004 09:39:19 -0000 1.108.2.1
+++ msgqueue.c 13 Dec 2004 16:18:17 -0000 1.108.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: msgqueue.c,v 1.108.2.1 2004/12/13 09:39:19 hyperion Exp $
+/* $Id: msgqueue.c,v 1.108.2.2 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.87.2.2 -r1.87.2.3
--- painting.c 13 Dec 2004 09:39:19 -0000 1.87.2.2
+++ painting.c 13 Dec 2004 16:18:17 -0000 1.87.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: painting.c,v 1.87.2.2 2004/12/13 09:39:19 hyperion Exp $
+ * $Id: painting.c,v 1.87.2.3 2004/12/13 16:18:17 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.47.2.2 -r1.47.2.3
--- stubs.c 13 Dec 2004 09:39:20 -0000 1.47.2.2
+++ stubs.c 13 Dec 2004 16:18:18 -0000 1.47.2.3
@@ -1,4 +1,4 @@
-/* $Id: stubs.c,v 1.47.2.2 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: stubs.c,v 1.47.2.3 2004/12/13 16:18:18 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.67.8.1 -r1.67.8.2
--- windc.c 13 Dec 2004 09:39:20 -0000 1.67.8.1
+++ windc.c 13 Dec 2004 16:18:18 -0000 1.67.8.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: windc.c,v 1.67.8.1 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: windc.c,v 1.67.8.2 2004/12/13 16:18:18 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.250.2.1 -r1.250.2.2
--- window.c 13 Dec 2004 09:39:20 -0000 1.250.2.1
+++ window.c 13 Dec 2004 16:18:18 -0000 1.250.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: window.c,v 1.250.2.1 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: window.c,v 1.250.2.2 2004/12/13 16:18:18 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.124.2.1 -r1.124.2.2
--- winpos.c 13 Dec 2004 09:39:20 -0000 1.124.2.1
+++ winpos.c 13 Dec 2004 16:18:18 -0000 1.124.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: winpos.c,v 1.124.2.1 2004/12/13 09:39:20 hyperion Exp $
+/* $Id: winpos.c,v 1.124.2.2 2004/12/13 16:18:18 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/ntuser
diff -u -r1.67.2.1 -r1.67.2.2
--- winsta.c 13 Dec 2004 09:39:20 -0000 1.67.2.1
+++ winsta.c 13 Dec 2004 16:18:18 -0000 1.67.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: winsta.c,v 1.67.2.1 2004/12/13 09:39:20 hyperion Exp $
+ * $Id: winsta.c,v 1.67.2.2 2004/12/13 16:18:18 hyperion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
reactos/subsys/win32k/objects
diff -u -r1.81.2.1 -r1.81.2.2
--- bitmaps.c 13 Dec 2004 09:39:21 -0000 1.81.2.1
+++ bitmaps.c 13 Dec 2004 16:18:18 -0000 1.81.2.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: bitmaps.c,v 1.81.2.1 2004/12/13 09:39:21 hyperion Exp $ */
+/* $Id: bitmaps.c,v 1.81.2.2 2004/12/13 16:18:18 hyperion Exp $ */
#include <w32k.h>
#define IN_RECT(r,x,y) \
reactos/subsys/win32k/objects
diff -u -r1.40.10.2 -r1.40.10.3
--- brush.c 13 Dec 2004 09:39:21 -0000 1.40.10.2
+++ brush.c 13 Dec 2004 16:18:18 -0000 1.40.10.3
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: brush.c,v 1.40.10.2 2004/12/13 09:39:21 hyperion Exp $
+ * $Id: brush.c,v 1.40.10.3 2004/12/13 16:18:18 hyperion Exp $
*/
#include <w32k.h>
reactos/subsys/win32k/objects
diff -u -r1.42.10.2 -r1.42.10.3
--- cliprgn.c 13 Dec 2004 09:39:21 -0000 1.42.10.2
+++ cliprgn.c 13 Dec 2004 16:18:18 -0000 1.42.10.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: cliprgn.c,v 1.42.10.2 2004/12/13 09:39:21 hyperion Exp $ */
+/* $Id: cliprgn.c,v 1.42.10.3 2004/12/13 16:18:18 hyperion Exp $ */
#include <w32k.h>
int FASTCALL
reactos/subsys/win32k/objects
diff -u -r1.50.10.1 -r1.50.10.2
--- color.c 13 Dec 2004 09:39:21 -0000 1.50.10.1
+++ color.c 13 Dec 2004 16:18:18 -0000 1.50.10.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: color.c,v 1.50.10.1 2004/12/13 09:39:21 hyperion Exp $ */
+/* $Id: color.c,v 1.50.10.2 2004/12/13 16:18:18 hyperion Exp $ */
#include <w32k.h>
// FIXME: Use PXLATEOBJ logicalToSystem instead of int *mapping
reactos/subsys/win32k/objects
diff -u -r1.147.2.2 -r1.147.2.3
--- dc.c 13 Dec 2004 09:39:21 -0000 1.147.2.2
+++ dc.c 13 Dec 2004 16:18:18 -0000 1.147.2.3
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: dc.c,v 1.147.2.2 2004/12/13 09:39:21 hyperion Exp $
+/* $Id: dc.c,v 1.147.2.3 2004/12/13 16:18:18 hyperion Exp $
*
* DC.C - Device context functions
*
reactos/subsys/win32k/objects
diff -u -r1.56.12.1 -r1.56.12.2
--- dib.c 13 Dec 2004 09:39:22 -0000 1.56.12.1
+++ dib.c 13 Dec 2004 16:18:19 -0000 1.56.12.2
@@ -1,5 +1,5 @@
/*
- * $Id: dib.c,v 1.56.12.1 2004/12/13 09:39:22 hyperion Exp $
+ * $Id: dib.c,v 1.56.12.2 2004/12/13 16:18:19 hyperion Exp $
*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
reactos/subsys/win32k/objects
diff -u -r1.52.10.1 -r1.52.10.2
--- fillshap.c 13 Dec 2004 09:39:22 -0000 1.52.10.1
+++ fillshap.c 13 Dec 2004 16:18:19 -0000 1.52.10.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: fillshap.c,v 1.52.10.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: fillshap.c,v 1.52.10.2 2004/12/13 16:18:19 hyperion Exp $ */
#include <w32k.h>
/*
reactos/subsys/win32k/objects
diff -u -r1.73.6.1 -r1.73.6.2
--- gdiobj.c 13 Dec 2004 09:39:22 -0000 1.73.6.1
+++ gdiobj.c 13 Dec 2004 16:18:19 -0000 1.73.6.2
@@ -19,7 +19,7 @@
/*
* GDIOBJ.C - GDI object manipulation routines
*
- * $Id: gdiobj.c,v 1.73.6.1 2004/12/13 09:39:22 hyperion Exp $
+ * $Id: gdiobj.c,v 1.73.6.2 2004/12/13 16:18:19 hyperion Exp $
*/
#include <w32k.h>
@@ -364,6 +364,7 @@
if(GdiHdr->LockingThread == NULL)
{
BOOL Ret;
+ PW32PROCESS W32Process = PsGetWin32Process();
ULONG Type = Entry->Type << 16;
/* Clear the type field so when unlocking the handle it gets finally deleted */
@@ -372,6 +373,11 @@
/* unlock the handle slot */
InterlockedExchange(&Entry->ProcessId, 0);
+
+ if(W32Process != NULL)
+ {
+ InterlockedDecrement(&W32Process->GDIObjects);
+ }
/* call the cleanup routine. */
Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), Type);
@@ -817,6 +823,7 @@
if(Entry->Type == 0 && GdiHdr->Locks == 0)
{
PPAGED_LOOKASIDE_LIST LookasideList;
+ PW32PROCESS W32Process = PsGetWin32Process();
DWORD Type = GDI_HANDLE_GET_TYPE(hObj);
ASSERT(ProcessId != 0); /* must not delete a global handle!!!! */
@@ -825,6 +832,11 @@
Entry->KernelData = NULL;
InterlockedExchange(&Entry->ProcessId, 0);
+ if(W32Process != NULL)
+ {
+ InterlockedDecrement(&W32Process->GDIObjects);
+ }
+
/* call the cleanup routine. */
Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), Type);
reactos/subsys/win32k/objects
diff -u -r1.37.10.1 -r1.37.10.2
--- line.c 13 Dec 2004 09:39:22 -0000 1.37.10.1
+++ line.c 13 Dec 2004 16:18:19 -0000 1.37.10.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: line.c,v 1.37.10.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: line.c,v 1.37.10.2 2004/12/13 16:18:19 hyperion Exp $ */
#include <w32k.h>
// Some code from the WINE project source (www.winehq.com)
reactos/subsys/win32k/objects
diff -u -r1.20.12.1 -r1.20.12.2
--- palette.c 13 Dec 2004 09:39:22 -0000 1.20.12.1
+++ palette.c 13 Dec 2004 16:18:19 -0000 1.20.12.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: palette.c,v 1.20.12.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: palette.c,v 1.20.12.2 2004/12/13 16:18:19 hyperion Exp $ */
#include <w32k.h>
#ifndef NO_MAPPING
reactos/subsys/win32k/objects
diff -u -r1.16.10.1 -r1.16.10.2
--- pen.c 13 Dec 2004 09:39:22 -0000 1.16.10.1
+++ pen.c 13 Dec 2004 16:18:19 -0000 1.16.10.2
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: pen.c,v 1.16.10.1 2004/12/13 09:39:22 hyperion Exp $
+ * $Id: pen.c,v 1.16.10.2 2004/12/13 16:18:19 hyperion Exp $
*/
#include <w32k.h>
reactos/subsys/win32k/objects
diff -u -r1.23.8.1 -r1.23.8.2
--- print.c 13 Dec 2004 09:39:22 -0000 1.23.8.1
+++ print.c 13 Dec 2004 16:18:19 -0000 1.23.8.2
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: print.c,v 1.23.8.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: print.c,v 1.23.8.2 2004/12/13 16:18:19 hyperion Exp $ */
#include <w32k.h>
INT
reactos/subsys/win32k/objects
diff -u -r1.62.10.1 -r1.62.10.2
--- region.c 13 Dec 2004 09:39:22 -0000 1.62.10.1
+++ region.c 13 Dec 2004 16:18:19 -0000 1.62.10.2
@@ -113,7 +113,7 @@
* the y-x-banding that's so nice to have...
*/
-/* $Id: region.c,v 1.62.10.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: region.c,v 1.62.10.2 2004/12/13 16:18:19 hyperion Exp $ */
#include <w32k.h>
#include <win32k/float.h>
reactos/subsys/win32k/objects
diff -u -r1.112.4.1 -r1.112.4.2
--- text.c 13 Dec 2004 09:39:22 -0000 1.112.4.1
+++ text.c 13 Dec 2004 16:18:22 -0000 1.112.4.2
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: text.c,v 1.112.4.1 2004/12/13 09:39:22 hyperion Exp $ */
+/* $Id: text.c,v 1.112.4.2 2004/12/13 16:18:22 hyperion Exp $ */
#include <w32k.h>
#include <ft2build.h>
reactos/tools
diff -u -r1.95.2.2 -r1.95.2.3
--- helper.mk 13 Dec 2004 09:39:25 -0000 1.95.2.2
+++ helper.mk 13 Dec 2004 16:18:22 -0000 1.95.2.3
@@ -1,4 +1,4 @@
-# $Id: helper.mk,v 1.95.2.2 2004/12/13 09:39:25 hyperion Exp $
+# $Id: helper.mk,v 1.95.2.3 2004/12/13 16:18:22 hyperion Exp $
#
# Helper makefile for ReactOS modules
# Variables this makefile accepts:
reactos/apps/utils/net/route
diff -N makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ makefile 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,17 @@
+PATH_TO_TOP = ../../../..
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = console
+
+TARGET_NAME = route
+
+TARGET_SDKLIBS = ws2_32.a iphlpapi.a ntdll.a
+
+TARGET_OBJECTS = $(TARGET_NAME).o
+
+TARGET_GCCLIBS =
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
reactos/apps/utils/net/route
diff -N route.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ route.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,157 @@
+/* Poor man's route
+ *
+ * Supported commands:
+ *
+ * "print"
+ * "add" target ["mask" mask] gw ["metric" metric]
+ * "delete" target gw
+ *
+ * Goals:
+ *
+ * Flexible, simple
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include <iphlpapi.h>
+#include <winsock2.h>
+
+#define IPBUF 17
+#define IN_ADDR_OF(x) *((struct in_addr *)&(x))
+
+int usage() {
+ fprintf( stderr,
+ "route usage:\n"
+ "route print\n"
+ " prints the route table\n"
+ "route add <target> [mask <mask>] <gw> [metric <m>]\n"
+ " adds a route\n"
+ "route delete <target> <gw>\n"
+ " deletes a route\n" );
+ return 1;
+}
+
+int print_routes() {
+ PMIB_IPFORWARDTABLE IpForwardTable;
+ DWORD Error;
+ ULONG Size = 0;
+ char Destination[IPBUF], Gateway[IPBUF], Netmask[IPBUF],
+ Index[IPBUF], Metric[IPBUF];
+ int i;
+
+ if( (Error = GetIpForwardTable( NULL, &Size, TRUE )) ==
+ ERROR_INSUFFICIENT_BUFFER ) {
+ IpForwardTable = malloc( Size );
+ Error = GetIpForwardTable( IpForwardTable, &Size, TRUE );
+ }
+
+ if( Error == ERROR_SUCCESS ) {
+ printf( "%-16s%-16s%-16s%-10s%-10s\n",
+ "Destination",
+ "Netmask",
+ "Gateway",
+ "Index",
+ "Metric" );
+ for( i = 0; i < IpForwardTable->dwNumEntries; i++ ) {
+ strcpy( Destination,
+ inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
+ dwForwardDest) ) );
+ strcpy( Netmask,
+ inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
+ dwForwardMask) ) );
+ strcpy( Gateway,
+ inet_ntoa( IN_ADDR_OF(IpForwardTable->table[i].
+ dwForwardNextHop) ) );
+
+ printf( "%-16s%-16s%-16s%-10d%-10d\n",
+ Destination,
+ Netmask,
+ Gateway,
+ IpForwardTable->table[i].dwForwardIfIndex,
+ IpForwardTable->table[i].dwForwardMetric1 );
+ }
+
+ free( IpForwardTable );
+
+ return ERROR_SUCCESS;
+ } else {
+ fprintf( stderr, "Route enumerate failed\n" );
+ return Error;
+ }
+}
+
+int convert_add_cmd_line( PMIB_IPFORWARDROW RowToAdd,
+ int argc, char **argv ) {
+ int i;
+
+ if( argc > 1 ) RowToAdd->dwForwardDest = inet_addr( argv[0] );
+ else return FALSE;
+ for( i = 1; i < argc; i++ ) {
+ if( !strcasecmp( argv[i], "mask" ) ) {
+ i++; if( i >= argc ) return FALSE;
+ RowToAdd->dwForwardMask = inet_addr( argv[i] );
+ } else if( !strcasecmp( argv[i], "metric" ) ) {
+ i++; if( i >= argc ) return FALSE;
+ RowToAdd->dwForwardMetric1 = atoi( argv[i] );
+ } else {
+ RowToAdd->dwForwardNextHop = inet_addr( argv[i] );
+ }
+ }
+
+ return TRUE;
+}
+
+int add_route( int argc, char **argv ) {
+ MIB_IPFORWARDROW RowToAdd = { 0 };
+ DWORD Error;
+
+ if( argc < 2 || !convert_add_cmd_line( &RowToAdd, argc, argv ) ) {
+ fprintf( stderr,
+ "route add usage:\n"
+ "route add <target> [mask <mask>] <gw> [metric <m>]\n"
+ " Adds a route to the IP route table.\n"
+ " <target> is the network or host to add a route to.\n"
+ " <mask> is the netmask to use (autodetected if unspecified)\n"
+ " <gw> is the gateway to use to access the network\n"
+ " <m> is the metric to use (lower is preferred)\n" );
+ return 1;
+ }
+
+ if( (Error = CreateIpForwardEntry( &RowToAdd )) == ERROR_SUCCESS )
+ return 0;
+
+ fprintf( stderr, "Route addition failed\n" );
+ return Error;
+}
+
+int del_route( int argc, char **argv ) {
+ MIB_IPFORWARDROW RowToDel = { 0 };
+ DWORD Error;
+
+ if( argc < 2 || !convert_add_cmd_line( &RowToDel, argc, argv ) ) {
+ fprintf( stderr,
+ "route delete usage:\n"
+ "route delete <target> <gw>\n"
+ " Removes a route from the IP route table.\n"
+ " <target> is the network or host to add a route to.\n"
+ " <gw> is the gateway to remove the route from.\n" );
+ return 1;
+ }
+
+ if( (Error = DeleteIpForwardEntry( &RowToDel )) == ERROR_SUCCESS )
+ return 0;
+
+ fprintf( stderr, "Route addition failed\n" );
+ return Error;
+}
+
+int main( int argc, char **argv ) {
+ if( argc < 2 ) return usage();
+ else if( !strcasecmp( argv[1], "print" ) )
+ return print_routes();
+ else if( !strcasecmp( argv[1], "add" ) )
+ return add_route( argc-2, argv+2 );
+ else if( !strcasecmp( argv[1], "delete" ) )
+ return del_route( argc-2, argv+2 );
+ else return usage();
+}
reactos/apps/utils/net/route
diff -N route.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ route.rc 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+/* $Id: route.rc,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $ */
+
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 Win32 Route\0"
+#define REACTOS_STR_INTERNAL_NAME "route\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "route.exe\0"
+#define REACTOS_STR_ORIGINAL_COPYRIGHT "Art Yerkes (arty@users.sourceforge.net)\0"
+#include <reactos/version.rc>
reactos/drivers/video/miniport/xboxvmp
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,8 @@
+junk.tmp
+base.tmp
+temp.exp
+xboxvmp.coff
+*.o
+*.sym
+*.sys
+*.map
reactos/drivers/video/miniport/xboxvmp
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,20 @@
+PATH_TO_TOP = ../../../..
+
+TARGET_TYPE = driver
+
+TARGET_NAME = xboxvmp
+
+TARGET_DDKLIBS = videoprt.a ntoskrnl.a
+
+TARGET_CFLAGS = -Werror -Wall -I$(PATH_TO_TOP)/ntoskrnl/include -D__USE_W32API
+
+TARGET_OBJECTS = \
+ xboxvmp.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+# Automatic dependency tracking
+DEP_OBJECTS := $(TARGET_OBJECTS)
+include $(PATH_TO_TOP)/tools/depend.mk
reactos/drivers/video/miniport/xboxvmp
diff -N xboxvmp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ xboxvmp.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,597 @@
+/*
+ * ReactOS Xbox miniport video driver
+ *
+ * Based on VBE miniport video driver
+ * Copyright (C) 2004 Filip Navara
+ *
+ * Power Management and VBE 1.2 support
+ * Copyright (C) 2004 Magnus Olsen
+ *
+ * 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.
+ *
+ * TODO:
+ * - Check input parameters everywhere.
+ * - Call VideoPortVerifyAccessRanges to reserve the memory we're about
+ * to map.
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "xboxvmp.h"
+
+#define I2C_IO_BASE 0xc000
+
+#define CONTROL_FRAMEBUFFER_ADDRESS_OFFSET 0x600800
+
+/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
+
+VP_STATUS STDCALL
+DriverEntry(IN PVOID Context1, IN PVOID Context2)
+{
+ VIDEO_HW_INITIALIZATION_DATA InitData;
+
+ VideoPortZeroMemory(&InitData, sizeof(InitData));
+ InitData.AdapterInterfaceType = PCIBus;
+ InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
+ InitData.HwFindAdapter = XboxVmpFindAdapter;
+ InitData.HwInitialize = XboxVmpInitialize;
+ InitData.HwStartIO = XboxVmpStartIO;
+ InitData.HwResetHw = XboxVmpResetHw;
+ InitData.HwGetPowerState = XboxVmpGetPowerState;
+ InitData.HwSetPowerState = XboxVmpSetPowerState;
+ InitData.HwDeviceExtensionSize = sizeof(XBOXVMP_DEVICE_EXTENSION);
+
+ return VideoPortInitialize(Context1, Context2, &InitData, NULL);
+}
+
+/*
+ * XboxVmpFindAdapter
+ *
+ * Detects the Xbox Nvidia display adapter.
+ */
+
+VP_STATUS STDCALL
+XboxVmpFindAdapter(
+ IN PVOID HwDeviceExtension,
+ IN PVOID HwContext,
+ IN PWSTR ArgumentString,
+ IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
+ OUT PUCHAR Again)
+{
+ PXBOXVMP_DEVICE_EXTENSION XboxVmpDeviceExtension;
+ VIDEO_ACCESS_RANGE AccessRanges[3];
+ VP_STATUS Status;
+
+ DPRINT("XboxVmpFindAdapter\n");
+
+ XboxVmpDeviceExtension = (PXBOXVMP_DEVICE_EXTENSION) HwDeviceExtension;
+ Status = VideoPortGetAccessRanges(HwDeviceExtension, 0, NULL, 3, AccessRanges,
+ NULL, NULL, NULL);
+
+ if (NO_ERROR == Status)
+ {
+ XboxVmpDeviceExtension->PhysControlStart = AccessRanges[0].RangeStart;
+ XboxVmpDeviceExtension->ControlLength = AccessRanges[0].RangeLength;
+ XboxVmpDeviceExtension->PhysFrameBufferStart = AccessRanges[1].RangeStart;
+ }
+
+ return Status;
+}
+
+/*
+ * XboxVmpInitialize
+ *
+ * Performs the first initialization of the adapter, after the HAL has given
+ * up control of the video hardware to the video port driver.
+ */
+
+BOOLEAN STDCALL
+XboxVmpInitialize(PVOID HwDeviceExtension)
+{
+ PXBOXVMP_DEVICE_EXTENSION XboxVmpDeviceExtension;
+ ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
+ ULONG Length;
+
+ DPRINT("XboxVmpInitialize\n");
+
+ XboxVmpDeviceExtension = (PXBOXVMP_DEVICE_EXTENSION) HwDeviceExtension;
+
+ Length = XboxVmpDeviceExtension->ControlLength;
+ XboxVmpDeviceExtension->VirtControlStart = NULL;
+ if (NO_ERROR != VideoPortMapMemory(HwDeviceExtension,
+ XboxVmpDeviceExtension->PhysControlStart,
+ &Length, &inIoSpace,
+ &XboxVmpDeviceExtension->VirtControlStart))
+ {
+ DPRINT1("Failed to map control memory\n");
+ return FALSE;
+ }
+ DPRINT("Mapped 0x%x bytes of control mem at 0x%x to virt addr 0x%x\n",
+ XboxVmpDeviceExtension->ControlLength,
+ XboxVmpDeviceExtension->PhysControlStart.u.LowPart,
+ XboxVmpDeviceExtension->VirtControlStart);
+
+ return TRUE;
+}
+
+/*
+ * XboxVmpStartIO
+ *
+ * Processes the specified Video Request Packet.
+ */
+
+BOOLEAN STDCALL
+XboxVmpStartIO(
+ PVOID HwDeviceExtension,
+ PVIDEO_REQUEST_PACKET RequestPacket)
+{
+ BOOL Result;
+
+ RequestPacket->StatusBlock->Status = STATUS_UNSUCCESSFUL;
+
+ switch (RequestPacket->IoControlCode)
+ {
+ case IOCTL_VIDEO_SET_CURRENT_MODE:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_SET_CURRENT_MODE\n");
+ if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
+ {
+ RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+ return TRUE;
+ }
+ Result = XboxVmpSetCurrentMode(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ (PVIDEO_MODE)RequestPacket->InputBuffer,
+ RequestPacket->StatusBlock);
+ break;
+
+ case IOCTL_VIDEO_RESET_DEVICE:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_RESET_DEVICE\n");
+ Result = XboxVmpResetDevice(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ RequestPacket->StatusBlock);
+ break;
+
+ case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_MAP_VIDEO_MEMORY\n");
+ if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
+ RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
+ {
+ RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+ return TRUE;
+ }
+ Result = XboxVmpMapVideoMemory(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ (PVIDEO_MEMORY)RequestPacket->InputBuffer,
+ (PVIDEO_MEMORY_INFORMATION)RequestPacket->OutputBuffer,
+ RequestPacket->StatusBlock);
+ break;
+
+ case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_UNMAP_VIDEO_MEMORY\n");
+ if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
+ {
+ RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+ return TRUE;
+ }
+ Result = XboxVmpUnmapVideoMemory(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ (PVIDEO_MEMORY)RequestPacket->InputBuffer,
+ RequestPacket->StatusBlock);
+ break;
+
+ case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES\n");
+ if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
+ {
+ RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+ return TRUE;
+ }
+ Result = XboxVmpQueryNumAvailModes(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ (PVIDEO_NUM_MODES)RequestPacket->OutputBuffer,
+ RequestPacket->StatusBlock);
+ break;
+
+ case IOCTL_VIDEO_QUERY_AVAIL_MODES:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_QUERY_AVAIL_MODES\n");
+ if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
+ {
+ RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+ return TRUE;
+ }
+ Result = XboxVmpQueryAvailModes(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
+ RequestPacket->StatusBlock);
+ break;
+
+ case IOCTL_VIDEO_QUERY_CURRENT_MODE:
+ DPRINT("XboxVmpStartIO IOCTL_VIDEO_QUERY_CURRENT_MODE\n");
+ if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
+ {
+ RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+ return TRUE;
+ }
+ Result = XboxVmpQueryCurrentMode(
+ (PXBOXVMP_DEVICE_EXTENSION)HwDeviceExtension,
+ (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
+ RequestPacket->StatusBlock);
+ break;
+
+ default:
+ DPRINT("XboxVmpStartIO 0x%x not implemented\n");
+ RequestPacket->StatusBlock->Status = STATUS_NOT_IMPLEMENTED;
+ return FALSE;
+ }
+
+ if (Result)
+ {
+ RequestPacket->StatusBlock->Status = STATUS_SUCCESS;
+ }
+
+ return TRUE;
+}
+
+/*
+ * XboxVmpResetHw
+ *
+ * This function is called to reset the hardware to a known state.
+ */
+
+BOOLEAN STDCALL
+XboxVmpResetHw(
+ PVOID DeviceExtension,
+ ULONG Columns,
+ ULONG Rows)
+{
+ DPRINT("XboxVmpResetHw\n");
+
+ if (! XboxVmpResetDevice((PXBOXVMP_DEVICE_EXTENSION) DeviceExtension, NULL))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * XboxVmpGetPowerState
+ *
+ * Queries whether the device can support the requested power state.
+ */
+
+VP_STATUS STDCALL
+XboxVmpGetPowerState(
+ PVOID HwDeviceExtension,
+ ULONG HwId,
+ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
+{
+ DPRINT1("XboxVmpGetPowerState is not supported\n");
+
+ return ERROR_NOT_SUPPORTED;
+}
+
+/*
+ * XboxVmpSetPowerState
+ *
+ * Sets the power state of the specified device
+ */
+
+VP_STATUS STDCALL
+XboxVmpSetPowerState(
+ PVOID HwDeviceExtension,
+ ULONG HwId,
+ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
+{
+ DPRINT1("XboxVmpSetPowerState not supported\n");
+
+ return ERROR_NOT_SUPPORTED;
+}
+
+/*
+ * VBESetCurrentMode
+ *
+ * Sets the adapter to the specified operating mode.
+ */
+
+BOOL FASTCALL
+XboxVmpSetCurrentMode(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MODE RequestedMode,
+ PSTATUS_BLOCK StatusBlock)
+{
+ if (0 != RequestedMode->RequestedMode)
+ {
+ return FALSE;
+ }
+
+ /* Nothing to do, really. We only support a single mode and we're already
+ in that mode */
+ return TRUE;
+}
+
+/*
+ * XboxVmpResetDevice
+ *
+ * Resets the video hardware to the default mode, to which it was initialized
+ * at system boot.
+ */
+
+BOOL FASTCALL
+XboxVmpResetDevice(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PSTATUS_BLOCK StatusBlock)
+{
+ /* There is nothing to be done here */
+
+ return TRUE;
+}
+
+/*
+ * XboxVmpMapVideoMemory
+ *
+ * Maps the video hardware frame buffer and video RAM into the virtual address
+ * space of the requestor.
+ */
+
+BOOL FASTCALL
+XboxVmpMapVideoMemory(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MEMORY RequestedAddress,
+ PVIDEO_MEMORY_INFORMATION MapInformation,
+ PSTATUS_BLOCK StatusBlock)
+{
+ PHYSICAL_ADDRESS FrameBuffer;
+ ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
+ SYSTEM_BASIC_INFORMATION BasicInfo;
+ ULONG Length;
+
+ StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
+
+ FrameBuffer.u.HighPart = 0;
+ if (NT_SUCCESS(ZwQuerySystemInformation(SystemBasicInformation,
+ (PVOID) &BasicInfo,
+ sizeof(SYSTEM_BASIC_INFORMATION),
+ &Length)))
+ {
+ FrameBuffer.u.LowPart = BasicInfo.HighestPhysicalPage * PAGE_SIZE;
+ }
+ else
+ {
+ DPRINT1("ZwQueryBasicInformation failed, assuming 64MB total memory\n");
+ FrameBuffer.u.LowPart = 60 * 1024 * 1024;
+ }
+
+ FrameBuffer.QuadPart += DeviceExtension->PhysFrameBufferStart.QuadPart;
+ MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
+ MapInformation->VideoRamLength = 4 * 1024 * 1024;
+ VideoPortMapMemory(DeviceExtension, FrameBuffer,
+ &MapInformation->VideoRamLength, &inIoSpace,
+ &MapInformation->VideoRamBase);
+
+ MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
+ MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
+
+ /* Tell the nVidia controller about the framebuffer */
+ *((PULONG)((char *) DeviceExtension->VirtControlStart + CONTROL_FRAMEBUFFER_ADDRESS_OFFSET)) = FrameBuffer.u.LowPart;
+
+ DPRINT("Mapped 0x%x bytes of phys mem at 0x%x to virt addr 0x%x\n",
+ MapInformation->VideoRamLength, FrameBuffer.u.LowPart, MapInformation->VideoRamBase);
+
+ return TRUE;
+}
+
+/*
+ * VBEUnmapVideoMemory
+ *
+ * Releases a mapping between the virtual address space and the adapter's
+ * frame buffer and video RAM.
+ */
+
+BOOL FASTCALL
+XboxVmpUnmapVideoMemory(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MEMORY VideoMemory,
+ PSTATUS_BLOCK StatusBlock)
+{
+ VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
+ NULL);
+
+ return TRUE;
+}
+
+/*
+ * XboxVmpQueryNumAvailModes
+ *
+ * Returns the number of video modes supported by the adapter and the size
+ * in bytes of the video mode information, which can be used to allocate a
+ * buffer for an IOCTL_VIDEO_QUERY_AVAIL_MODES request.
+ */
+
+BOOL FASTCALL
+XboxVmpQueryNumAvailModes(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_NUM_MODES Modes,
+ PSTATUS_BLOCK StatusBlock)
+{
+ Modes->NumModes = 1;
+ Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
+ StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
+ return TRUE;
+}
+
+static BOOL
+ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus)
+{
+ int nRetriesToLive=50;
+
+ while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800))
+ {
+ ; /* Franz's spin while bus busy with any master traffic */
+ }
+
+ while (0 != nRetriesToLive--)
+ {
+ UCHAR b;
+ int temp;
+
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1);
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister);
+
+ temp = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0));
+ WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */
+
+ switch (Size)
+ {
+ case 4:
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */
+ break;
+ case 2:
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */
+ break;
+ default:
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a); // BYTE
+ break;
+ }
+
+ b = 0;
+
+ while (0 == (b & 0x36))
+ {
+ b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0));
+ }
+
+ if (0 != (b & 0x24))
+ {
+ /* printf("I2CTransmitByteGetReturn error %x\n", b); */
+ }
+
+ if(0 == (b & 0x10))
+ {
+ /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */
+ }
+ else
+ {
+ switch (Size)
+ {
+ case 4:
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ break;
+ case 2:
+ *Data_to_smbus = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6));
+ break;
+ default:
+ *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+ break;
+ }
+
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static BOOL
+I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return)
+{
+ return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return);
+}
+
+/*
+ * XboxVmpQueryAvailModes
+ *
+ * Returns information about each video mode supported by the adapter.
+ */
+
+BOOL FASTCALL
+XboxVmpQueryAvailModes(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MODE_INFORMATION VideoMode,
+ PSTATUS_BLOCK StatusBlock)
+{
+ return XboxVmpQueryCurrentMode(DeviceExtension, VideoMode, StatusBlock);
+}
+
+/*
+ * VBEQueryCurrentMode
+ *
+ * Returns information about current video mode.
+ */
+
+BOOL FASTCALL
+XboxVmpQueryCurrentMode(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MODE_INFORMATION VideoMode,
+ PSTATUS_BLOCK StatusBlock)
+{
+ ULONG AvMode;
+
+ VideoMode->Length = sizeof(VIDEO_MODE_INFORMATION);
+ VideoMode->ModeIndex = 0;
+ if (I2CTransmitByteGetReturn(0x10, 0x04, &AvMode))
+ {
+ if (1 == AvMode) /* HDTV */
+ {
+ VideoMode->VisScreenWidth = 720;
+ }
+ else
+ {
+ /* FIXME Other possible values of AvMode:
+ * 0 - AV_SCART_RGB
+ * 2 - AV_VGA_SOG
+ * 4 - AV_SVIDEO
+ * 6 - AV_COMPOSITE
+ * 7 - AV_VGA
+ * other AV_COMPOSITE
+ */
+ VideoMode->VisScreenWidth = 640;
+ }
+ }
+ else
+ {
+ VideoMode->VisScreenWidth = 640;
+ }
+ VideoMode->VisScreenHeight = 480;
+ VideoMode->ScreenStride = VideoMode->VisScreenWidth * 4;
+ VideoMode->NumberOfPlanes = 1;
+ VideoMode->BitsPerPlane = 32;
+ VideoMode->Frequency = 1;
+ VideoMode->XMillimeter = 0; /* FIXME */
+ VideoMode->YMillimeter = 0; /* FIXME */
+ VideoMode->NumberRedBits = 8;
+ VideoMode->NumberGreenBits = 8;
+ VideoMode->NumberBlueBits = 8;
+ VideoMode->RedMask = 0xff0000;
+ VideoMode->GreenMask = 0x00ff00;
+ VideoMode->BlueMask = 0x0000ff;
+ VideoMode->VideoMemoryBitmapWidth = VideoMode->VisScreenWidth;
+ VideoMode->VideoMemoryBitmapHeight = VideoMode->VisScreenHeight;
+ VideoMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
+ VIDEO_MODE_NO_OFF_SCREEN;
+ VideoMode->DriverSpecificAttributeFlags = 0;
+
+ StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);
+
+ return TRUE;
+}
+
+/* EOF */
reactos/drivers/video/miniport/xboxvmp
diff -N xboxvmp.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ xboxvmp.h 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,130 @@
+/*
+ * ReactOS Xbox miniport video driver
+ *
+ * Based on VBE miniport video driver
+ * Copyright (C) 2004 Filip Navara
+ *
+ * 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.
+ */
+
+#ifndef XBOXVMP_H
+#define XBOXVMP_H
+
+/* INCLUDES *******************************************************************/
+
+#include "stddef.h"
+#include "windef.h"
+#include "wingdi.h"
+#include <ddk/miniport.h>
+#include <ddk/video.h>
+#include <ddk/ntddvdeo.h>
+#include <ddk/ntapi.h>
+
+#define NDEBUG
+#include <debug.h>
+
+typedef struct
+{
+ PHYSICAL_ADDRESS PhysControlStart;
+ ULONG ControlLength;
+ PVOID VirtControlStart;
+ PHYSICAL_ADDRESS PhysFrameBufferStart;
+} XBOXVMP_DEVICE_EXTENSION, *PXBOXVMP_DEVICE_EXTENSION;
+
+VP_STATUS STDCALL
+XboxVmpFindAdapter(
+ IN PVOID HwDeviceExtension,
+ IN PVOID HwContext,
+ IN PWSTR ArgumentString,
+ IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
+ OUT PUCHAR Again);
+
+BOOLEAN STDCALL
+XboxVmpInitialize(PVOID HwDeviceExtension);
+
+BOOLEAN STDCALL
+XboxVmpStartIO(
+ PVOID HwDeviceExtension,
+ PVIDEO_REQUEST_PACKET RequestPacket);
+
+BOOLEAN STDCALL
+XboxVmpResetHw(
+ PVOID DeviceExtension,
+ ULONG Columns,
+ ULONG Rows);
+
+VP_STATUS STDCALL
+XboxVmpGetPowerState(
+ PVOID HwDeviceExtension,
+ ULONG HwId,
+ PVIDEO_POWER_MANAGEMENT VideoPowerControl);
+
+VP_STATUS STDCALL
+XboxVmpSetPowerState(
+ PVOID HwDeviceExtension,
+ ULONG HwId,
+ PVIDEO_POWER_MANAGEMENT VideoPowerControl);
+
+BOOL FASTCALL
+XboxVmpSetCurrentMode(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MODE RequestedMode,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpResetDevice(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpMapVideoMemory(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MEMORY RequestedAddress,
+ PVIDEO_MEMORY_INFORMATION MapInformation,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpUnmapVideoMemory(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MEMORY VideoMemory,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpQueryNumAvailModes(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_NUM_MODES Modes,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpQueryAvailModes(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MODE_INFORMATION ReturnedModes,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpQueryCurrentMode(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_MODE_INFORMATION VideoModeInfo,
+ PSTATUS_BLOCK StatusBlock);
+
+BOOL FASTCALL
+XboxVmpSetColorRegisters(
+ PXBOXVMP_DEVICE_EXTENSION DeviceExtension,
+ PVIDEO_CLUT ColorLookUpTable,
+ PSTATUS_BLOCK StatusBlock);
+
+#endif /* XBOXVMP_H */
+
+/* EOF */
reactos/drivers/video/miniport/xboxvmp
diff -N xboxvmp.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ xboxvmp.rc 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+/* $Id: xboxvmp.rc,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $ */
+
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "Xbox Miniport Device Driver\0"
+#define REACTOS_STR_INTERNAL_NAME "xboxvmp\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "xboxvmp.sys\0"
+#include <reactos/version.rc>
reactos/hal/halx86/generic
diff -N adapter.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ adapter.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,679 @@
+/* $Id: adapter.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/x86/adapter.c (from ntoskrnl/io/adapter.c)
+ * PURPOSE: DMA handling
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * Vizzini (vizzini@plasmic.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ * 18-Oct-2003 Vizzini DMA support modifications
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <ddk/iotypes.h>
+#define NDEBUG
+#include <internal/debug.h>
+#include <hal.h>
+
+/* FUNCTIONS *****************************************************************/
+
+/* NOTE: IoAllocateAdapterChannel in NTOSKRNL.EXE */
+
+
+NTSTATUS STDCALL
+HalAllocateAdapterChannel(
+ PADAPTER_OBJECT AdapterObject,
+ PWAIT_CONTEXT_BLOCK WaitContextBlock,
+ ULONG NumberOfMapRegisters,
+ PDRIVER_CONTROL ExecutionRoutine)
+/*
+ * FUNCTION: Sets up an ADAPTER_OBJECT with map registers
+ * ARGUMENTS:
+ * - AdapterObject: pointer to an ADAPTER_OBJECT to set up
+ * - WaitContextBlock: Context block to be used with ExecutionRoutine
+ * - NumberOfMapRegisters: number of map registers requested
+ * - ExecutionRoutine: callback to call when map registers are allocated
+ * RETURNS:
+ * STATUS_INSUFFICIENT_RESOURCES if map registers cannot be allocated
+ * STATUS_SUCCESS in all other cases, including if the callbacak had
+ * to be queued for later delivery
+ * NOTES:
+ * - the ADAPTER_OBJECT struct is undocumented; please make copious
+ * notes in hal.h if anything is changed or improved since there is
+ * no other documentation for this data structure
+ * BUGS:
+ * - it's possible that some of this code is in the wrong place
+ * - there are many unhandled cases
+ */
+{
+ LARGE_INTEGER MinAddress;
+ LARGE_INTEGER MaxAddress;
+ LARGE_INTEGER BoundryAddressMultiple;
+ IO_ALLOCATION_ACTION Retval;
+
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /*
+ FIXME: return STATUS_INSUFFICIENT_RESOURCES if the NumberOfMapRegisters
+ requested is larger than the value returned by IoGetDmaAdapter.
+ */
+
+ /* set up the wait context block in case we can't run right away */
+ WaitContextBlock->DeviceRoutine = ExecutionRoutine;
+ WaitContextBlock->NumberOfMapRegisters = NumberOfMapRegisters;
+
+ /* returns true if queued, else returns false and sets the queue to busy */
+ if(KeInsertDeviceQueue(&AdapterObject->ChannelWaitQueue, &WaitContextBlock->WaitQueueEntry))
+ return STATUS_SUCCESS;
+
+ /* 24-bit max address due to 16-bit dma controllers */
+ MinAddress.QuadPart = 0x0000000;
+ MaxAddress.QuadPart = 0x1000000;
+ BoundryAddressMultiple.QuadPart = 0;
+
+ /* why 64K alignment? */
+ /*
+ * X86 lacks map registers, so for now, we allocate a contiguous
+ * block of physical memory <16MB and copy all DMA buffers into
+ * that. This can be optimized.
+ *
+ * FIXME: We propably shouldn't allocate the memory here for common
+ * buffer transfers. See a comment in IoMapTransfer about common buffer
+ * support.
+ */
+ AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory(
+ NumberOfMapRegisters * PAGE_SIZE,
+ MinAddress,
+ MaxAddress,
+ BoundryAddressMultiple,
+ MmCached,
+ 0x10000 );
+
+ if(!AdapterObject->MapRegisterBase)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ AdapterObject->CommittedMapRegisters = NumberOfMapRegisters;
+
+ /* call the client's AdapterControl callback with its map registers and context */
+ Retval = ExecutionRoutine(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+ AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+ /*
+ * KeepObject: don't free any resources; the ADAPTER_OBJECT is still in use
+ * and the caller will call IoFreeAdapterChannel later
+ *
+ * DeallocateObject: Deallocate the map registers and release the ADAPTER_OBJECT
+ * so someone else can use it
+ *
+ * DeallocateObjectKeepRegisters: release the ADAPTER_OBJECT but hang on to
+ * the map registers. The client will later call IoFreeMapRegisters.
+ *
+ * NOTE - IoFreeAdapterChannel runs the queue, so it must be called
+ * unless the adapter object is not to be freed.
+ */
+ if( Retval == DeallocateObject )
+ IoFreeAdapterChannel(AdapterObject);
+ else if(Retval == DeallocateObjectKeepRegisters)
+ {
+ /* don't free the allocated map registers - this is what IoFreeAdapterChannel checks */
+ AdapterObject->CommittedMapRegisters = 0;
+ IoFreeAdapterChannel(AdapterObject);
+ }
+
+ /*
+ * if we don't call IoFreeAdapterChannel, the next device won't get de-queued,
+ * which is what we want.
+ */
+
+ return STATUS_SUCCESS;
+}
+
+
+BOOLEAN
+HalpGrowMapBuffers(
+ IN PADAPTER_OBJECT AdapterObject,
+ IN ULONG SizeOfMapBuffers)
+/*
+ * FUNCTION: Allocate initial, or additional, map buffers for IO adapters.
+ * ARGUMENTS:
+ * AdapterObject: DMA adapter to allocate buffers for.
+ * SizeOfMapBuffers: Size of the map buffers to allocate
+ * NOTES:
+ * - Needs to be tested...
+ */
+{
+ //ULONG PagesToAllocate = BYTES_TO_PAGES(SizeOfMapBuffers);
+
+ /* TODO: Allocation */
+
+ return TRUE;
+}
+
+PADAPTER_OBJECT STDCALL
+HalpAllocateAdapterEx(
+ ULONG NumberOfMapRegisters,
+ BOOLEAN IsMaster,
+ BOOLEAN Dma32BitAddresses)
+/*
+ * FUNCTION: Allocates an ADAPTER_OBJECT, optionally creates the Master Adapter.
+ * ARGUMENTS:
+ * - NumberOfMapRegisters: Number of map registers to allocate
+ * - IsMaster: Wether this is a Master Device or not
+ * - Dma32BitAddresses: Wether 32-bit Addresses are supported
+ * RETURNS:
+ * - Pointer to Adapter Object, or NULL if failure.
+ * BUGS:
+ * - Some stuff is unhandled/incomplete
+ */
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ ULONG ObjectSize;
+ ULONG BitmapSize;
+ NTSTATUS Status;
+ ULONG AllowedMapRegisters = 64;
+ PADAPTER_OBJECT AdapterObject;
+ HANDLE Handle;
+
+ /* Allocate the Master Adapter if we haven't already
+ but make sure we're not asked to do it now, and also check if we need it */
+ if ((MasterAdapter == NULL) && (!IsMaster) && (NumberOfMapRegisters)) {
+
+ /* Allocate and Save */
+ DPRINT("Allocating the Master Adapter Object\n");
+ MasterAdapter = HalpAllocateAdapterEx(NumberOfMapRegisters,
+ TRUE,
+ Dma32BitAddresses);
+
+ /* Cancel on Failure */
+ DPRINT("Checking if Master Adapter was allocated properly\n");
+ if (!MasterAdapter) return NULL;
+ }
+
+ /* Initialize the Object Attributes for the Adapter Object */
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ OBJ_PERMANENT,
+ NULL,
+ NULL);
+
+ /* Check if this is the Master Adapter, in which case we need to allocate the bitmap */
+ if (IsMaster) {
+ /* Size due to the Bitmap + Bytes in the Bitmap Buffer (8 bytes, 64 bits)*/
+ BitmapSize = sizeof(RTL_BITMAP) + AllowedMapRegisters / 8;
+
+ /* We will put the Bitmap Buffer after the Adapter Object for simplicity */
+ ObjectSize = sizeof(ADAPTER_OBJECT) + BitmapSize;
+ } else {
+ ObjectSize = sizeof(ADAPTER_OBJECT);
+ }
+
+ /* Create and Allocate the Object */
+ DPRINT("Creating the Object\n");
+ Status = ObCreateObject(KernelMode,
+ IoAdapterObjectType,
+ &ObjectAttributes,
+ KernelMode,
+ NULL,
+ ObjectSize,
+ 0,
+ 0,
+ (PVOID)&AdapterObject);
+
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* Add a Reference */
+ DPRINT("Referencing the Object\n");
+ Status = ObReferenceObjectByPointer(AdapterObject,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ IoAdapterObjectType,
+ KernelMode);
+
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* It's a Valid Object, so now we can play with the memory */
+ RtlZeroMemory(AdapterObject, sizeof(ADAPTER_OBJECT));
+
+ /* Insert it into the Object Table */
+ DPRINT("Inserting the Object\n");
+ Status = ObInsertObject(AdapterObject,
+ NULL,
+ FILE_READ_DATA | FILE_WRITE_DATA,
+ 0,
+ NULL,
+ &Handle);
+
+ if (!NT_SUCCESS(Status)) return NULL;
+
+ /* We don't want the handle */
+ NtClose(Handle);
+
+ /* Set up the Adapter Object fields */
+ AdapterObject->MapRegistersPerChannel = 1;
+
+ /* Set the Master if needed (master only needed if we use Map Registers) */
+ if (NumberOfMapRegisters) AdapterObject->MasterAdapter = MasterAdapter;
+
+ /* Initalize the Channel Wait queue, which every adapter has */
+ DPRINT("Initializing the Device Queue of the Object\n");
+ KeInitializeDeviceQueue(&AdapterObject->ChannelWaitQueue);
+
+ /* Initialize the SpinLock, Queue and Bitmap, which are kept in the Master Adapter only */
+ if (IsMaster) {
+
+ DPRINT("Initializing the Master Adapter Stuff\n");
+ KeInitializeSpinLock(&AdapterObject->SpinLock);
+ InitializeListHead(&AdapterObject->AdapterQueue);
+
+ /* As said previously, we put them here for simplicity */
+ AdapterObject->MapRegisters = (PVOID)(AdapterObject + 1);
+
+ /* Set up Bitmap */
+ RtlInitializeBitMap(AdapterObject->MapRegisters,
+ (PULONG)(AdapterObject->MapRegisters + 1),
+ AllowedMapRegisters);
+
+ /* Reset the Bitmap */
+ RtlSetAllBits(AdapterObject->MapRegisters);
+ AdapterObject->NumberOfMapRegisters = 0;
+ AdapterObject->CommittedMapRegisters = 0;
+
+ /* Allocate Memory for the Map Registers */
+ AdapterObject->MapRegisterBase = ExAllocatePool(NonPagedPool,
+ AllowedMapRegisters * sizeof(DWORD));
+
+ /* Clear them */
+ RtlZeroMemory(AdapterObject->MapRegisterBase, AllowedMapRegisters * sizeof(DWORD));
+
+ /* Allocate the contigous memory */
+ DPRINT("Allocating Buffers\n");
+ HalpGrowMapBuffers(AdapterObject, 0x1000000);
+ }
+
+ DPRINT("Adapter Object allocated\n");
+ return AdapterObject;
+}
+
+
+BOOLEAN STDCALL
+IoFlushAdapterBuffers (
+ PADAPTER_OBJECT AdapterObject,
+ PMDL Mdl,
+ PVOID MapRegisterBase,
+ PVOID CurrentVa,
+ ULONG Length,
+ BOOLEAN WriteToDevice)
+/*
+ * FUNCTION: flush any data remaining in the dma controller's memory into the host memory
+ * ARGUMENTS:
+ * AdapterObject: the adapter object to flush
+ * Mdl: original MDL to flush data into
+ * MapRegisterBase: map register base that was just used by IoMapTransfer, etc
+ * CurrentVa: offset into Mdl to be flushed into, same as was passed to IoMapTransfer
+ * Length: length of the buffer to be flushed into
+ * WriteToDevice: True if it's a write, False if it's a read
+ * RETURNS:
+ * TRUE in all cases
+ * NOTES:
+ * - This copies data from the map register-backed buffer to the user's target buffer.
+ * Data is not in the user buffer until this is called.
+ * - This is only meaningful on a read operation. Return immediately for a write.
+ */
+{
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ /* this can happen if the card supports scatter/gather */
+ if(!MapRegisterBase)
+ return TRUE;
+
+ /* mask out (disable) the dma channel */
+ if (AdapterObject->AdapterNumber == 1) {
+
+ /* Set this for Ease */
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+
+ /* Set Channel */
+ WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_SETMASK);
+ } else {
+ /* Set this for Ease */
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+
+ /* Set Channel */
+ WRITE_PORT_UCHAR(&DmaControl2->SingleMask, (AdapterObject->ChannelNumber - 4) | DMA_SETMASK);
+ }
+
+ if(WriteToDevice)
+ return TRUE;
+
+ memcpy(
+ (PVOID)((DWORD)MmGetSystemAddressForMdl( Mdl ) + (DWORD)CurrentVa - (DWORD)MmGetMdlVirtualAddress( Mdl )),
+ MapRegisterBase, Length );
+
+ return TRUE;
+}
+
+
+VOID STDCALL
+IoFreeAdapterChannel (PADAPTER_OBJECT AdapterObject)
+/*
+ * FUNCTION: frees DMA resources allocated by IoAllocateAdapterChannel
+ * ARGUMENTS:
+ * AdapterObject: Adapter object with resources to free
+ * NOTES:
+ * - This function releases the DMA adapter and optionally the map registers
+ * - After releasing the adapter, it checks the adapter's queue and runs
+ * each queued device object in series until the queue is empty
+ * - This is the only way the device queue is emptied.
+ */
+{
+ LARGE_INTEGER MaxAddress;
+ LARGE_INTEGER MinAddress;
+ LARGE_INTEGER BoundryAddressMultiple;
+ PWAIT_CONTEXT_BLOCK WaitContextBlock;
+ IO_ALLOCATION_ACTION Retval;
+
+ while(1)
+ {
+ /* To keep map registers, call here with the following set to 0 */
+ if(AdapterObject->CommittedMapRegisters)
+ IoFreeMapRegisters(AdapterObject, AdapterObject->MapRegisterBase, AdapterObject->CommittedMapRegisters);
+
+ if(!(WaitContextBlock = (PWAIT_CONTEXT_BLOCK)KeRemoveDeviceQueue(&AdapterObject->ChannelWaitQueue)))
+ break;
+
+ /*
+ * the following should really be done elsewhere since this
+ * function really can't return an error code. FIXME.
+ */
+
+ /* 24-bit max address due to 16-bit dma controllers */
+ MinAddress.QuadPart = 0x0000000;
+ MaxAddress.QuadPart = 0x1000000;
+ BoundryAddressMultiple.QuadPart = 0;
+
+ AdapterObject->MapRegisterBase = MmAllocateContiguousAlignedMemory(
+ WaitContextBlock->NumberOfMapRegisters * PAGE_SIZE,
+ MinAddress,
+ MaxAddress,
+ BoundryAddressMultiple,
+ MmCached,
+ 0x10000 );
+
+ if(!AdapterObject->MapRegisterBase)
+ return;
+
+ /* call the adapter control routine */
+ Retval = ((PDRIVER_CONTROL)WaitContextBlock->DeviceRoutine)(WaitContextBlock->DeviceObject, WaitContextBlock->CurrentIrp,
+ AdapterObject->MapRegisterBase, WaitContextBlock->DeviceContext);
+
+ if(Retval == KeepObject)
+ {
+ /* we're done until the caller manually calls IoFreeAdapterChannel */
+ break;
+ }
+ else if(Retval == DeallocateObjectKeepRegisters)
+ {
+ /* hide the map registers so they aren't deallocated next time around */
+ AdapterObject->CommittedMapRegisters = 0;
+ }
+ }
+}
+
+
+VOID STDCALL
+IoFreeMapRegisters (
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PVOID MapRegisterBase,
+ IN ULONG NumberOfMapRegisters)
+/*
+ * FUNCTION: free map registers reserved by the system for a DMA
+ * ARGUMENTS:
+ * AdapterObject: dma adapter to free map registers on
+ * MapRegisterBase: hadle to map registers to free
+ * NumberOfRegisters: number of map registers to be freed
+ * NOTES:
+ * - XXX real windows has a funky interdependence between IoFreeMapRegisters
+ * and IoFreeAdapterChannel
+ * BUGS:
+ * - needs to be improved to use a real map register implementation
+ */
+{
+ if( AdapterObject->CommittedMapRegisters )
+ {
+ MmFreeContiguousMemory(AdapterObject->MapRegisterBase);
+ AdapterObject->MapRegisterBase = 0;
+ }
+}
+
+
+PHYSICAL_ADDRESS STDCALL
+IoMapTransfer (
+ IN PADAPTER_OBJECT AdapterObject,
+ IN PMDL Mdl,
+ IN PVOID MapRegisterBase,
+ IN PVOID CurrentVa,
+ IN OUT PULONG Length,
+ IN BOOLEAN WriteToDevice)
+/*
+ * FUNCTION: map a dma for transfer and do the dma if it's a slave
+ * ARGUMENTS:
+ * AdapterObject: adapter object to do the dma on. busmaster may pass NULL.
+ * Mdl: locked-down user buffer to DMA in to or out of
+ * MapRegisterBase: handle to map registers to use for this dma. allways NULL
+ * when doing s/g.
+ * CurrentVa: index into Mdl to transfer into/out of
+ * Length: length of transfer in/out. Only modified on out when doing s/g.
+ * WriteToDevice: TRUE if it's an output dma, FALSE otherwise
+ * RETURNS:
+ * If a busmaster: A logical address that can be used to program a dma controller
+ * Otherwise: nothing meaningful
+ * NOTES:
+ * - This function does a copyover to contiguous memory <16MB
+ * - If it's a slave transfer, this function actually performs it.
+ * BUGS:
+ * - If the controller supports scatter/gather, the copyover should not happen
+ */
+{
+ PHYSICAL_ADDRESS Address;
+ KIRQL OldIrql;
+ UCHAR Mode;
+
+#if defined(__GNUC__)
+ Address.QuadPart = 0ULL;
+#else
+ Address.QuadPart = 0;
+#endif
+
+ /* Isa System (slave) DMA? */
+ if (MapRegisterBase && !AdapterObject->MasterDevice)
+ {
+
+ KeAcquireSpinLock(&AdapterObject->SpinLock, &OldIrql);
+
+ /*
+ * FIXME: Handle case when doing common-buffer System DMA. In this case,
+ * the buffer described by MDL is already phys. contiguous and below
+ * 16 mega. Driver makes a one-shot call to IoMapTransfer during init.
+ * to program controller with the common-buffer.
+ *
+ * UPDATE: Common buffer support is in place, but it's not done in a
+ * clean way. We use the buffer passed by the MDL in case that the
+ * adapter object is marked as auto initialize. I'm not sure if this
+ * is correct and if not, how to do it properly. Note that it's also
+ * possible to allocate the common buffer with different adapter object
+ * and IoMapTransfer must still work in this case. Eventually this should
+ * be cleaned up somehow or at least this comment modified to reflect
+ * the reality.
+ * -- Filip Navara, 19/07/2004
+ */
+
+ /* Get the mode for easier coding */
+ Mode = AdapterObject->AdapterMode;
+
+ /* if it is a write to the device, copy the caller buffer to the low buffer */
+ if ((WriteToDevice) && !((PDMA_MODE)&Mode)->AutoInitialize)
+ {
+ memcpy(MapRegisterBase,
+ (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
+ *Length );
+ }
+
+ /* Writer Adapter Mode, transfer type */
+ ((PDMA_MODE)&Mode)->TransferType = (WriteToDevice ? WRITE_TRANSFER : READ_TRANSFER);
+
+ // program up the dma controller, and return
+ if (!((PDMA_MODE)&Mode)->AutoInitialize) {
+ Address = MmGetPhysicalAddress( MapRegisterBase );
+ } else {
+ Address = MmGetPhysicalAddress( CurrentVa );
+ }
+
+ /* 16-bit DMA has a shifted length */
+ if (AdapterObject->Width16Bits) *Length = (*Length >> 1);
+
+ /* Make the Transfer */
+ if (AdapterObject->AdapterNumber == 1) {
+
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
+
+ /* Reset Register */
+ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+
+ /* Set the Mode */
+ WRITE_PORT_UCHAR(&DmaControl1->Mode, (UCHAR)(Mode));
+
+ /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+
+ /* Set the Length */
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1));
+ WRITE_PORT_UCHAR(&DmaControl1->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1) >> 8);
+
+ /* Unmask the Channel */
+ WRITE_PORT_UCHAR(&DmaControl1->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ } else {
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa; /* For Writing Less Code */
+
+ /* Reset Register */
+ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+
+ /* Set the Mode */
+ WRITE_PORT_UCHAR(&DmaControl2->Mode, (UCHAR)(Mode));
+
+ /* Set the Page Register (apparently always 0 for us if I trust the previous comment) */
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseAddress, 0);
+
+ /* Set the Length */
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1));
+ WRITE_PORT_UCHAR(&DmaControl2->DmaAddressCount[AdapterObject->ChannelNumber].DmaBaseCount,
+ (UCHAR)((*Length) - 1) >> 8);
+
+ /* Unmask the Channel */
+ WRITE_PORT_UCHAR(&DmaControl2->SingleMask, AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+
+ /* Release Spinlock */
+ KeReleaseSpinLock(&AdapterObject->SpinLock, OldIrql);
+
+ /*
+ NOTE: Return value should be ignored when doing System DMA.
+ Maybe return some more obvious invalid address here (thou returning
+ MapRegisterBase is also wrong;-)to catch invalid use?
+ */
+ Address.QuadPart = (ULONG)MapRegisterBase;
+ return Address;
+ }
+
+
+ /*
+ Busmaster with s/g support?
+ NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
+ being NULL is used to detect a s/g busmaster.
+ */
+ if ((!AdapterObject && !MapRegisterBase) ||
+ (AdapterObject && AdapterObject->MasterDevice && AdapterObject->ScatterGather))
+ {
+ /*
+ Just return the passed VA's corresponding phys. address.
+ Update length to the number of phys. contiguous bytes found.
+ */
+
+ PULONG MdlPages;
+ ULONG MdlPageIndex, PhysContiguousLen;
+ ULONG PhysAddress;
+
+ MdlPages = (PULONG)(Mdl + 1);
+
+ /* Get VA's corresponding mdl phys. page index */
+ MdlPageIndex = ((ULONG)CurrentVa - (ULONG)Mdl->StartVa) / PAGE_SIZE;
+
+ /* Get phys. page containing the VA */
+ PhysAddress = MdlPages[MdlPageIndex];
+
+ PhysContiguousLen = PAGE_SIZE - BYTE_OFFSET(CurrentVa);
+
+ /* VA to map may span several contiguous phys. pages (unlikely) */
+ while (PhysContiguousLen < *Length &&
+ MdlPages[MdlPageIndex++] + PAGE_SIZE == MdlPages[MdlPageIndex])
+ {
+ /*
+ Note that allways adding PAGE_SIZE may make PhysContiguousLen greater
+ than Length if buffer doesn't end on page boundary. Take this
+ into consideration below.
+ */
+ PhysContiguousLen += PAGE_SIZE;
+ }
+
+ if (PhysContiguousLen < *Length)
+ {
+ *Length = PhysContiguousLen;
+ }
+
+ //add offset to phys. page address
+ Address.QuadPart = PhysAddress + BYTE_OFFSET(CurrentVa);
+ return Address;
+ }
+
+
+ /*
+ Busmaster without s/g support?
+ NOTE: old docs allowed busmasters to pass a NULL Adapter. In this case, MapRegisterBase
+ not being NULL is used to detect a non s/g busmaster.
+ */
+ if ((!AdapterObject && MapRegisterBase) ||
+ (AdapterObject && AdapterObject->MasterDevice && !AdapterObject->ScatterGather))
+ {
+ /*
+ NOTE: Busmasters doing common-buffer DMA shouldn't call IoMapTransfer, but I don't
+ know if it's illegal... Maybe figure out what to do in this case...
+ */
+
+ if( WriteToDevice )
+ {
+ memcpy(MapRegisterBase,
+ (char*)MmGetSystemAddressForMdl(Mdl) + ((ULONG)CurrentVa - (ULONG)MmGetMdlVirtualAddress(Mdl)),
+ *Length );
+ }
+
+ return MmGetPhysicalAddress(MapRegisterBase);
+ }
+
+ DPRINT("IoMapTransfer: Unsupported operation\n");
+ KEBUGCHECK(0);
+ return Address;
+}
+
+
+/* EOF */
+
+
+
+
reactos/hal/halx86/generic
diff -N beep.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ beep.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/beep.c
+ * PURPOSE: Speaker function (it's only one)
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 31/01/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* CONSTANTS *****************************************************************/
+
+#define TIMER2 0x42
+#define TIMER3 0x43
+#define PORT_B 0x61
+#define CLOCKFREQ 1193167
+
+
+/* FUNCTIONS *****************************************************************/
+/*
+ * FUNCTION: Beeps the speaker.
+ * ARGUMENTS:
+ * Frequency = If 0, the speaker will be switched off, otherwise
+ * the speaker beeps with the specified frequency.
+ */
+
+BOOLEAN
+STDCALL
+HalMakeBeep (
+ ULONG Frequency
+ )
+{
+ UCHAR b;
+ ULONG flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ /* speaker off */
+ b = READ_PORT_UCHAR((PUCHAR)PORT_B);
+ WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(b & 0xFC));
+
+ if (Frequency)
+ {
+ DWORD Divider = CLOCKFREQ / Frequency;
+
+ if (Divider > 0x10000)
+ {
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+
+ return FALSE;
+ }
+
+ /* set timer divider */
+ WRITE_PORT_UCHAR((PUCHAR)TIMER3, 0xB6);
+ WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)(Divider & 0xFF));
+ WRITE_PORT_UCHAR((PUCHAR)TIMER2, (UCHAR)((Divider>>8) & 0xFF));
+
+ /* speaker on */
+ WRITE_PORT_UCHAR((PUCHAR)PORT_B, (UCHAR)(READ_PORT_UCHAR((PUCHAR)PORT_B) | 0x03));
+ }
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+
+ return TRUE;
+}
+
reactos/hal/halx86/generic
diff -N bus.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ bus.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,532 @@
+/* $Id: bus.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/bus.c
+ * PURPOSE: Bus functions
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ *
+ *
+ * TODO:
+ * - Add bus handler functions for all busses
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *******************************************************************/
+
+#define TAG_BUS TAG('B', 'U', 'S', 'H')
+
+KSPIN_LOCK HalpBusHandlerSpinLock = {0,};
+LIST_ENTRY HalpBusHandlerList;
+
+
+/* FUNCTIONS *****************************************************************/
+
+static NTSTATUS STDCALL
+HalpNoAdjustResourceList(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PCM_RESOURCE_LIST Resources)
+{
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS STDCALL
+HalpNoAssignSlotResources(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PUNICODE_STRING RegistryPath,
+ PUNICODE_STRING DriverClassName,
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT DeviceObject,
+ ULONG SlotNumber,
+ PCM_RESOURCE_LIST *AllocatedResources)
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
+
+static ULONG STDCALL
+HalpNoBusData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ return 0;
+}
+
+
+static ULONG STDCALL
+HalpNoGetInterruptVector(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ return 0;
+}
+
+
+static ULONG STDCALL
+HalpNoTranslateBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ return 0;
+}
+
+
+PBUS_HANDLER
+HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
+ BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler = NULL;
+
+ DPRINT("HalpAllocateBusHandler()\n");
+
+ BusHandler = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(BUS_HANDLER),
+ TAG_BUS);
+ if (BusHandler == NULL)
+ return NULL;
+
+ RtlZeroMemory(BusHandler,
+ sizeof(BUS_HANDLER));
+
+ InsertTailList(&HalpBusHandlerList,
+ &BusHandler->Entry);
+
+ BusHandler->InterfaceType = InterfaceType;
+ BusHandler->BusDataType = BusDataType;
+ BusHandler->BusNumber = BusNumber;
+
+ /* initialize default bus handler functions */
+ BusHandler->GetBusData = HalpNoBusData;
+ BusHandler->SetBusData = HalpNoBusData;
+ BusHandler->AdjustResourceList = HalpNoAdjustResourceList;
+ BusHandler->AssignSlotResources = HalpNoAssignSlotResources;
+ BusHandler->GetInterruptVector = HalpNoGetInterruptVector;
+ BusHandler->TranslateBusAddress = HalpNoTranslateBusAddress;
+
+ /* any more ?? */
+
+ DPRINT("HalpAllocateBusHandler() done\n");
+
+ return BusHandler;
+}
+
+
+VOID
+HalpInitBusHandlers(VOID)
+{
+ PBUS_HANDLER BusHandler;
+
+ /* General preparations */
+ KeInitializeSpinLock(&HalpBusHandlerSpinLock);
+ InitializeListHead(&HalpBusHandlerList);
+
+ /* Initialize hal dispatch tables */
+ HalQuerySystemInformation = HalpQuerySystemInformation;
+
+#if 0
+ HalSetSystemInformation = HalpSetSystemInformation;
+
+ HalQueryBusSlots = HalpQueryBusSlots;
+#endif
+
+ /* Add system bus handler */
+ BusHandler = HalpAllocateBusHandler(Internal,
+ ConfigurationSpaceUndefined,
+ 0);
+ if (BusHandler == NULL)
+ return;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetSystemInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslateSystemBusAddress;
+
+ /* Add cmos bus handler */
+ BusHandler = HalpAllocateBusHandler(InterfaceTypeUndefined,
+ Cmos,
+ 0);
+ if (BusHandler == NULL)
+ return;
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetCmosData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetCmosData;
+
+ /* Add isa bus handler */
+ BusHandler = HalpAllocateBusHandler(Isa,
+ ConfigurationSpaceUndefined,
+ 0);
+ if (BusHandler == NULL)
+ return;
+
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetIsaInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslateIsaBusAddress;
+
+ /* Add MicroChannel bus handler */
+ BusHandler = HalpAllocateBusHandler(MicroChannel,
+ Pos,
+ 0);
+ if (BusHandler == NULL)
+ return;
+
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetMicroChannelData;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliHandlerForBus(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->InterfaceType == InterfaceType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->BusDataType == BusDataType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliReferenceHandlerForBus(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->InterfaceType == InterfaceType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ BusHandler->RefCount++;
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+PBUS_HANDLER FASTCALL
+HaliReferenceHandlerForConfigSpace(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber)
+{
+ PBUS_HANDLER BusHandler;
+ PLIST_ENTRY CurrentEntry;
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+
+ CurrentEntry = HalpBusHandlerList.Flink;
+ while (CurrentEntry != &HalpBusHandlerList)
+ {
+ BusHandler = (PBUS_HANDLER)CurrentEntry;
+ if (BusHandler->BusDataType == BusDataType &&
+ BusHandler->BusNumber == BusNumber)
+ {
+ BusHandler->RefCount++;
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+ return BusHandler;
+ }
+ CurrentEntry = CurrentEntry->Flink;
+ }
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+
+ return NULL;
+}
+
+
+VOID FASTCALL
+HaliDereferenceBusHandler(PBUS_HANDLER BusHandler)
+{
+ KIRQL OldIrql;
+
+ KeAcquireSpinLock(&HalpBusHandlerSpinLock,
+ &OldIrql);
+ BusHandler->RefCount--;
+ KeReleaseSpinLock(&HalpBusHandlerSpinLock,
+ OldIrql);
+}
+
+
+NTSTATUS STDCALL
+HalAdjustResourceList(PCM_RESOURCE_LIST Resources)
+{
+ PBUS_HANDLER BusHandler;
+ NTSTATUS Status;
+
+ BusHandler = HaliReferenceHandlerForBus(Resources->List[0].InterfaceType,
+ Resources->List[0].BusNumber);
+ if (BusHandler == NULL)
+ return STATUS_SUCCESS;
+
+ Status = BusHandler->AdjustResourceList(BusHandler,
+ Resources->List[0].BusNumber,
+ Resources);
+ HaliDereferenceBusHandler (BusHandler);
+
+ return Status;
+}
+
+
+NTSTATUS STDCALL
+HalAssignSlotResources(PUNICODE_STRING RegistryPath,
+ PUNICODE_STRING DriverClassName,
+ PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT DeviceObject,
+ INTERFACE_TYPE BusType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PCM_RESOURCE_LIST *AllocatedResources)
+{
+ PBUS_HANDLER BusHandler;
+ NTSTATUS Status;
+
+ BusHandler = HaliReferenceHandlerForBus(BusType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return STATUS_NOT_FOUND;
+
+ Status = BusHandler->AssignSlotResources(BusHandler,
+ BusNumber,
+ RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ SlotNumber,
+ AllocatedResources);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Status;
+}
+
+
+ULONG STDCALL
+HalGetBusData(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Length)
+{
+ return (HalGetBusDataByOffset(BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ 0,
+ Length));
+}
+
+
+ULONG STDCALL
+HalGetBusDataByOffset(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PBUS_HANDLER BusHandler;
+ ULONG Result;
+
+ BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return 0;
+
+ Result = BusHandler->GetBusData(BusHandler,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+
+ HaliDereferenceBusHandler (BusHandler);
+
+ return Result;
+}
+
+
+ULONG STDCALL
+HalGetInterruptVector(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ PBUS_HANDLER BusHandler;
+ ULONG Result;
+
+ BusHandler = HaliReferenceHandlerForBus(InterfaceType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return 0;
+
+ Result = BusHandler->GetInterruptVector(BusHandler,
+ BusNumber,
+ BusInterruptLevel,
+ BusInterruptVector,
+ Irql,
+ Affinity);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Result;
+}
+
+
+ULONG STDCALL
+HalSetBusData(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Length)
+{
+ return (HalSetBusDataByOffset(BusDataType,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ 0,
+ Length));
+}
+
+
+ULONG STDCALL
+HalSetBusDataByOffset(BUS_DATA_TYPE BusDataType,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PBUS_HANDLER BusHandler;
+ ULONG Result;
+
+ BusHandler = HaliReferenceHandlerForConfigSpace(BusDataType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return 0;
+
+ Result = BusHandler->SetBusData(BusHandler,
+ BusNumber,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Result;
+}
+
+
+BOOLEAN STDCALL
+HalTranslateBusAddress(INTERFACE_TYPE InterfaceType,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ PBUS_HANDLER BusHandler;
+ BOOLEAN Result;
+
+ BusHandler = HaliReferenceHandlerForBus(InterfaceType,
+ BusNumber);
+ if (BusHandler == NULL)
+ return FALSE;
+
+ Result = (BOOLEAN)BusHandler->TranslateBusAddress(BusHandler,
+ BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress);
+
+ HaliDereferenceBusHandler(BusHandler);
+
+ return Result;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N display.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ display.c 13 Dec 2004 16:18:23 -0000 1.3.2.1
@@ -0,0 +1,794 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 ReactOS Team
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: display.c,v 1.3.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/display.c
+ * PURPOSE: Blue screen display
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * Created 08/10/99
+ */
+
+/*
+ * Portions of this code are from the XFree86 Project and available from the
+ * following license:
+ *
+ * Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+ * NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the XFree86 Project shall
+ * not be used in advertising or otherwise to promote the sale, use or other
+ * dealings in this Software without prior written authorization from the
+ * XFree86 Project.
+*/
+
+/* DISPLAY OWNERSHIP
+ *
+ * So, who owns the physical display and is allowed to write to it?
+ *
+ * In MS NT, upon boot HAL owns the display. Somewhere in the boot
+ * sequence (haven't figured out exactly where or by who), some
+ * component calls HalAcquireDisplayOwnership. From that moment on,
+ * the display is owned by that component and is switched to graphics
+ * mode. The display is not supposed to return to text mode, except
+ * in case of a bug check. The bug check will call HalDisplayString
+ * to output a string to the text screen. HAL will notice that it
+ * currently doesn't own the display and will re-take ownership, by
+ * calling the callback function passed to HalAcquireDisplayOwnership.
+ * After the bugcheck, execution is halted. So, under NT, the only
+ * possible sequence of display modes is text mode -> graphics mode ->
+ * text mode (the latter hopefully happening very infrequently).
+ *
+ * Things are a little bit different in the current state of ReactOS.
+ * We want to have a functional interactive text mode. We should be
+ * able to switch from text mode to graphics mode when a GUI app is
+ * started and switch back to text mode when it's finished. Then, when
+ * another GUI app is started, another switch to and from graphics mode
+ * is possible. Also, when the system bugchecks in graphics mode we want
+ * to switch back to text mode to show the registers and stack trace.
+ * Last but not least, HalDisplayString is used a lot more in ReactOS,
+ * e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
+ * is present.
+ * 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
+ * As in NT, on boot HAL owns the display. When entering the text mode
+ * command interpreter, BLUE.SYS kicks in. It will write directly to the
+ * screen, more or less behind HALs back.
+ * When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
+ * This open call will end up in VIDEOPRT.SYS. That component will then
+ * take ownership of the display by calling HalAcquireDisplayOwnership.
+ * When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
+ * we want to give ownership of the display back to HAL. Using the
+ * standard exported HAL functions, that's a bit of a problem, because
+ * there is no function defined to do that. In NT, this is handled by
+ * HalDisplayString, but that solution isn't satisfactory in ReactOS,
+ * because HalDisplayString is (in some cases) also used to output debug
+ * messages. If we do it the NT way, the first debug message output while
+ * in graphics mode would switch the display back to text mode.
+ * So, instead, if HalDisplayString detects that HAL doesn't have ownership
+ * of the display, it doesn't do anything.
+ * To return ownership to HAL, a new function is exported,
+ * HalReleaseDisplayOwnership. This function is called by the DISPLAY
+ * device Close routine in VIDEOPRT.SYS. It is also called at the beginning
+ * of a bug check, so HalDisplayString is activated again.
+ * Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
+ * should also refrain from writing to the screen buffer. The text mode
+ * screen buffer might overlap the graphics mode screen buffer, so changing
+ * something in the text mode buffer might mess up the graphics screen. To
+ * allow BLUE.SYS to detect if HAL owns the display, another new function is
+ * exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
+ * check if it's allowed to touch the text mode buffer.
+ *
+ * In an ideal world, when HAL takes ownership of the display, it should set
+ * up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
+ * calls. Unfortunately, this will require HAL to setup a real-mode interrupt
+ * table etc. So, we chickened out of that by having the loader set up the
+ * display before switching to protected mode. If HAL is given back ownership
+ * after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
+ * since there is already support for them via the VideoPortInt10 routine.
+ */
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define SCREEN_SYNCHRONIZATION
+
+#define VGA_GRAPH_MEM 0xa0000
+#define VGA_CHAR_MEM 0xb8000
+#define VGA_END_MEM 0xbffff
+
+#define VGA_AC_INDEX 0x3c0
+#define VGA_AC_READ 0x3c1
+#define VGA_AC_WRITE 0x3c0
+
+#define VGA_MISC_WRITE 0x3c2
+
+#define VGA_SEQ_INDEX 0x3c4
+#define VGA_SEQ_DATA 0x3c5
+
+#define VGA_DAC_MASK 0x3c6
+#define VGA_DAC_READ_INDEX 0x3c7
+#define VGA_DAC_WRITE_INDEX 0x3c8
+#define VGA_DAC_DATA 0x3c9
+#define VGA_FEATURE_READ 0x3ca
+#define VGA_MISC_READ 0x3cc
+
+#define VGA_GC_INDEX 0x3ce
+#define VGA_GC_DATA 0x3cf
+
+#define VGA_CRTC_INDEX 0x3d4
+#define VGA_CRTC_DATA 0x3d5
+
+#define VGA_INSTAT_READ 0x3da
+
+#define VGA_SEQ_NUM_REGISTERS 5
+#define VGA_CRTC_NUM_REGISTERS 25
+#define VGA_GC_NUM_REGISTERS 9
+#define VGA_AC_NUM_REGISTERS 21
+
+#define CRTC_COLUMNS 0x01
+#define CRTC_OVERFLOW 0x07
+#define CRTC_ROWS 0x12
+#define CRTC_SCANLINES 0x09
+
+#define CRTC_CURHI 0x0e
+#define CRTC_CURLO 0x0f
+
+
+#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */
+#define CHAR_ATTRIBUTE 0x17 /* grey on blue */
+
+#define FONT_AMOUNT (8*8192)
+
+/* VARIABLES ****************************************************************/
+
+static ULONG CursorX = 0; /* Cursor Position */
+static ULONG CursorY = 0;
+static ULONG SizeX = 80; /* Display size */
+static ULONG SizeY = 25;
+
+static BOOLEAN DisplayInitialized = FALSE;
+static BOOLEAN HalOwnsDisplay = TRUE;
+
+static PUSHORT VideoBuffer = NULL;
+static PUCHAR GraphVideoBuffer = NULL;
+
+static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
+
+static UCHAR SavedTextPalette[768];
+static UCHAR SavedTextMiscOutReg;
+static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS];
+static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS];
+static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS];
+static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS];
+static UCHAR SavedTextFont[2][FONT_AMOUNT];
+static BOOLEAN TextPaletteEnabled = FALSE;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID FASTCALL
+HalClearDisplay (UCHAR CharAttribute)
+{
+ WORD *ptr = (WORD*)VideoBuffer;
+ ULONG i;
+
+ for (i = 0; i < SizeX * SizeY; i++, ptr++)
+ *ptr = ((CharAttribute << 8) + ' ');
+
+ CursorX = 0;
+ CursorY = 0;
+}
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+VOID STATIC
+HalScrollDisplay (VOID)
+{
+ PUSHORT ptr;
+ int i;
+
+ ptr = VideoBuffer + SizeX;
+ RtlMoveMemory(VideoBuffer,
+ ptr,
+ SizeX * (SizeY - 1) * 2);
+
+ ptr = VideoBuffer + (SizeX * (SizeY - 1));
+ for (i = 0; i < (int)SizeX; i++, ptr++)
+ {
+ *ptr = (CHAR_ATTRIBUTE << 8) + ' ';
+ }
+}
+
+VOID STATIC FASTCALL
+HalPutCharacter (CHAR Character)
+{
+ PUSHORT ptr;
+
+ ptr = VideoBuffer + ((CursorY * SizeX) + CursorX);
+ *ptr = (CHAR_ATTRIBUTE << 8) + Character;
+}
+
+VOID STATIC
+HalDisablePalette(VOID)
+{
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);
+ TextPaletteEnabled = FALSE;
+}
+
+VOID STATIC
+HalEnablePalette(VOID)
+{
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00);
+ TextPaletteEnabled = TRUE;
+}
+
+UCHAR STATIC FASTCALL
+HalReadGc(ULONG Index)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA));
+}
+
+VOID STATIC FASTCALL
+HalWriteGc(ULONG Index, UCHAR Value)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadSeq(ULONG Index)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA));
+}
+
+VOID STATIC FASTCALL
+HalWriteSeq(ULONG Index, UCHAR Value)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value);
+}
+
+VOID STATIC FASTCALL
+HalWriteAc(ULONG Index, UCHAR Value)
+{
+ if (TextPaletteEnabled)
+ {
+ Index &= ~0x20;
+ }
+ else
+ {
+ Index |= 0x20;
+ }
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadAc(ULONG Index)
+{
+ if (TextPaletteEnabled)
+ {
+ Index &= ~0x20;
+ }
+ else
+ {
+ Index |= 0x20;
+ }
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ));
+}
+
+VOID STATIC FASTCALL
+HalWriteCrtc(ULONG Index, UCHAR Value)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value);
+}
+
+UCHAR STATIC FASTCALL
+HalReadCrtc(ULONG Index)
+{
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
+ return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA));
+}
+
+VOID STATIC FASTCALL
+HalResetSeq(BOOLEAN Start)
+{
+ if (Start)
+ {
+ HalWriteSeq(0x00, 0x01);
+ }
+ else
+ {
+ HalWriteSeq(0x00, 0x03);
+ }
+}
+
+VOID STATIC FASTCALL
+HalBlankScreen(BOOLEAN On)
+{
+ UCHAR Scrn;
+
+ Scrn = HalReadSeq(0x01);
+
+ if (On)
+ {
+ Scrn &= ~0x20;
+ }
+ else
+ {
+ Scrn |= 0x20;
+ }
+
+ HalResetSeq(TRUE);
+ HalWriteSeq(0x01, Scrn);
+ HalResetSeq(FALSE);
+}
+
+VOID STATIC
+HalSaveFont(VOID)
+{
+ UCHAR Attr10;
+ UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4;
+ ULONG i;
+
+ /* Check if we are already in graphics mode. */
+ Attr10 = HalReadAc(0x10);
+ if (Attr10 & 0x01)
+ {
+ return;
+ }
+
+ /* Save registers. */
+ MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+ Gc4 = HalReadGc(0x04);
+ Gc5 = HalReadGc(0x05);
+ Gc6 = HalReadGc(0x06);
+ Seq2 = HalReadSeq(0x02);
+ Seq4 = HalReadSeq(0x04);
+
+ /* Force colour mode. */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01));
+
+ HalBlankScreen(FALSE);
+
+ for (i = 0; i < 2; i++)
+ {
+ /* Save font 1 */
+ HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
+ HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+ HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
+ HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
+ HalWriteGc(0x06, 0x05); /* Set graphics. */
+ memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
+ }
+
+ /* Restore registers. */
+ HalWriteAc(0x10, Attr10);
+ HalWriteSeq(0x02, Seq2);
+ HalWriteSeq(0x04, Seq4);
+ HalWriteGc(0x04, Gc4);
+ HalWriteGc(0x05, Gc5);
+ HalWriteGc(0x06, Gc6);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+
+ HalBlankScreen(TRUE);
+}
+
+VOID STATIC
+HalSaveMode(VOID)
+{
+ ULONG i;
+
+ SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+
+ for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+ {
+ SavedTextCrtcReg[i] = HalReadCrtc(i);
+ }
+
+ HalEnablePalette();
+ for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+ {
+ SavedTextAcReg[i] = HalReadAc(i);
+ }
+ HalDisablePalette();
+
+ for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+ {
+ SavedTextGcReg[i] = HalReadGc(i);
+ }
+
+ for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
+ {
+ SavedTextSeqReg[i] = HalReadSeq(i);
+ }
+}
+
+VOID STATIC
+HalDacDelay(VOID)
+{
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+ (VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
+}
+
+VOID STATIC
+HalSavePalette(VOID)
+{
+ ULONG i;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
+ for (i = 0; i < 768; i++)
+ {
+ SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
+ HalDacDelay();
+ }
+}
+
+VOID STATIC
+HalRestoreFont(VOID)
+{
+ UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
+ UCHAR Seq2, Seq4;
+ ULONG i;
+
+ /* Save registers. */
+ MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
+ Attr10 = HalReadAc(0x10);
+ Gc1 = HalReadGc(0x01);
+ Gc3 = HalReadGc(0x03);
+ Gc4 = HalReadGc(0x04);
+ Gc5 = HalReadGc(0x05);
+ Gc6 = HalReadGc(0x06);
+ Gc8 = HalReadGc(0x08);
+ Seq2 = HalReadSeq(0x02);
+ Seq4 = HalReadSeq(0x04);
+
+ /* Force into colour mode. */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10));
+
+ HalBlankScreen(FALSE);
+
+ HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */
+ HalWriteGc(0x08, 0xFF); /* Write all bits. */
+ HalWriteGc(0x01, 0x00); /* All planes from CPU. */
+
+ for (i = 0; i < 2; i++)
+ {
+ HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
+ HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
+ HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
+ HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
+ HalWriteGc(0x06, 0x05); /* Set graphics. */
+ memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
+ }
+
+ HalBlankScreen(TRUE);
+
+ /* Restore registers. */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
+ HalWriteAc(0x10, Attr10);
+ HalWriteGc(0x01, Gc1);
+ HalWriteGc(0x03, Gc3);
+ HalWriteGc(0x04, Gc4);
+ HalWriteGc(0x05, Gc5);
+ HalWriteGc(0x06, Gc6);
+ HalWriteGc(0x08, Gc8);
+ HalWriteSeq(0x02, Seq2);
+ HalWriteSeq(0x04, Seq4);
+}
+
+VOID STATIC
+HalRestoreMode(VOID)
+{
+ ULONG i;
+
+ WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
+
+ for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
+ {
+ HalWriteSeq(i, SavedTextSeqReg[i]);
+ }
+
+ /* Unlock CRTC registers 0-7 */
+ HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80));
+
+ for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
+ {
+ HalWriteCrtc(i, SavedTextCrtcReg[i]);
+ }
+
+ for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
+ {
+ HalWriteGc(i, SavedTextGcReg[i]);
+ }
+
+ HalEnablePalette();
+ for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
+ {
+ HalWriteAc(i, SavedTextAcReg[i]);
+ }
+ HalDisablePalette();
+}
+
+VOID STATIC
+HalRestorePalette(VOID)
+{
+ ULONG i;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
+ for (i = 0; i < 768; i++)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
+ HalDacDelay();
+ }
+ HalDisablePalette();
+}
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+VOID FASTCALL
+HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
+/*
+ * FUNCTION: Initalize the display
+ * ARGUMENTS:
+ * InitParameters = Parameters setup by the boot loader
+ */
+{
+ PHYSICAL_ADDRESS PhysBuffer;
+
+ if (! DisplayInitialized)
+ {
+ ULONG ScanLines;
+ ULONG Data;
+
+ PhysBuffer.u.HighPart = 0;
+ PhysBuffer.u.LowPart = VGA_GRAPH_MEM;
+ GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached);
+ if (NULL == GraphVideoBuffer)
+ {
+ return;
+ }
+ VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM));
+
+ /* Set cursor position */
+// CursorX = LoaderBlock->cursorx;
+// CursorY = LoaderBlock->cursory;
+ CursorX = 0;
+ CursorY = 0;
+
+ /* read screen size from the crtc */
+ /* FIXME: screen size should be read from the boot parameters */
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS);
+ SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS);
+ SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW);
+ Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+ SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
+ SizeY++;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES);
+ ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1;
+ SizeY = SizeY / ScanLines;
+
+#ifdef BOCHS_30ROWS
+ SizeY=30;
+#endif
+ HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
+
+ DisplayInitialized = TRUE;
+
+ /*
+ Save the VGA state at this point so we can restore it on a bugcheck.
+ */
+ HalSavePalette();
+ HalSaveMode();
+ HalSaveFont();
+ }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+VOID STDCALL
+HalReleaseDisplayOwnership(VOID)
+/*
+ * FUNCTION: Release ownership of display back to HAL
+ */
+{
+ if (HalResetDisplayParameters == NULL)
+ return;
+
+ if (HalOwnsDisplay == TRUE)
+ return;
+
+ if (!HalResetDisplayParameters(SizeX, SizeY))
+ {
+ HalRestoreMode();
+ HalRestoreFont();
+ HalRestorePalette();
+ }
+ HalOwnsDisplay = TRUE;
+ HalClearDisplay(CHAR_ATTRIBUTE);
+}
+
+
+VOID STDCALL
+HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * ResetDisplayParameters = Pointer to a driver specific
+ * reset routine.
+ */
+{
+ HalOwnsDisplay = FALSE;
+ HalResetDisplayParameters = ResetDisplayParameters;
+}
+
+VOID STDCALL
+HalDisplayString(IN PCH String)
+/*
+ * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
+ * already and displays a string
+ * ARGUMENT:
+ * string = ASCII string to display
+ * NOTE: Use with care because there is no support for returning from BSOD
+ * mode
+ */
+{
+ PCH pch;
+#ifdef SCREEN_SYNCHRONIZATION
+ int offset;
+#endif
+ static KSPIN_LOCK Lock;
+ KIRQL OldIrql;
+ ULONG Flags;
+
+ /* See comment at top of file */
+ if (! HalOwnsDisplay || ! DisplayInitialized)
+ {
+ return;
+ }
+
+ pch = String;
+
+ OldIrql = KfRaiseIrql(HIGH_LEVEL);
+ KiAcquireSpinLock(&Lock);
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+#ifdef SCREEN_SYNCHRONIZATION
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
+ offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8;
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
+ offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
+
+ CursorY = offset / SizeX;
+ CursorX = offset % SizeX;
+#endif
+
+ while (*pch != 0)
+ {
+ if (*pch == '\n')
+ {
+ CursorY++;
+ CursorX = 0;
+ }
+ else if (*pch == '\b')
+ {
+ if (CursorX > 0)
+ {
+ CursorX--;
+ }
+ }
+ else if (*pch != '\r')
+ {
+ HalPutCharacter (*pch);
+ CursorX++;
+
+ if (CursorX >= SizeX)
+ {
+ CursorY++;
+ CursorX = 0;
+ }
+ }
+
+ if (CursorY >= SizeY)
+ {
+ HalScrollDisplay ();
+ CursorY = SizeY - 1;
+ }
+
+ pch++;
+ }
+
+#ifdef SCREEN_SYNCHRONIZATION
+ offset = (CursorY * SizeX) + CursorX;
+
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff));
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
+ WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff));
+#endif
+ Ki386RestoreFlags(Flags);
+
+ KiReleaseSpinLock(&Lock);
+ KfLowerIrql(OldIrql);
+}
+
+VOID STDCALL
+HalQueryDisplayParameters(OUT PULONG DispSizeX,
+ OUT PULONG DispSizeY,
+ OUT PULONG CursorPosX,
+ OUT PULONG CursorPosY)
+{
+ if (DispSizeX)
+ *DispSizeX = SizeX;
+ if (DispSizeY)
+ *DispSizeY = SizeY;
+ if (CursorPosX)
+ *CursorPosX = CursorX;
+ if (CursorPosY)
+ *CursorPosY = CursorY;
+}
+
+
+VOID STDCALL
+HalSetDisplayParameters(IN ULONG CursorPosX,
+ IN ULONG CursorPosY)
+{
+ CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
+ CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
+}
+
+
+BOOLEAN STDCALL
+HalQueryDisplayOwnership(VOID)
+{
+ return !HalOwnsDisplay;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N dma.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dma.c 13 Dec 2004 16:18:23 -0000 1.2.2.1
@@ -0,0 +1,444 @@
+/* $Id: dma.c,v 1.2.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/dma.c
+ * PURPOSE: DMA functions
+ * PROGRAMMERS: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#define NDEBUG
+#include <internal/debug.h>
+#include <hal.h>
+
+/* Adapters for each channel */
+PADAPTER_OBJECT HalpEisaAdapter[8];
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+HalpInitDma (VOID)
+{
+ /* TODO: Initialize the first Map Buffer */
+}
+
+PVOID STDCALL
+HalAllocateCommonBuffer (PADAPTER_OBJECT AdapterObject,
+ ULONG Length,
+ PPHYSICAL_ADDRESS LogicalAddress,
+ BOOLEAN CacheEnabled)
+/*
+ * FUNCTION: Allocates memory that is visible to both the processor(s) and
+ * a dma device
+ * ARGUMENTS:
+ * AdapterObject = Adapter object representing the bus master or
+ * system dma controller
+ * Length = Number of bytes to allocate
+ * LogicalAddress = Logical address the driver can use to access the
+ * buffer
+ * CacheEnabled = Specifies if the memory can be cached
+ * RETURNS: The base virtual address of the memory allocated
+ * NULL on failure
+ * NOTES:
+ * CacheEnabled is ignored - it's all cache-disabled (like in NT)
+ * UPDATE: It's not ignored now. If that's wrong just modify the
+ * CacheEnabled comparsion below.
+ */
+{
+ PHYSICAL_ADDRESS LowestAddress, HighestAddress, BoundryAddressMultiple;
+ PVOID BaseAddress;
+
+ LowestAddress.QuadPart = 0;
+ BoundryAddressMultiple.QuadPart = 0;
+ HighestAddress.u.HighPart = 0;
+ if ((AdapterObject->Dma32BitAddresses) && (AdapterObject->MasterDevice)) {
+ HighestAddress.u.LowPart = 0xFFFFFFFF; /* 32Bit: 4GB address range */
+ } else {
+ HighestAddress.u.LowPart = 0x00FFFFFF; /* 24Bit: 16MB address range */
+ }
+
+ BaseAddress = MmAllocateContiguousAlignedMemory(
+ Length,
+ LowestAddress,
+ HighestAddress,
+ BoundryAddressMultiple,
+ CacheEnabled ? MmCached : MmNonCached,
+ 0x10000 );
+ if (!BaseAddress)
+ return 0;
+
+ *LogicalAddress = MmGetPhysicalAddress(BaseAddress);
+
+ return BaseAddress;
+}
+
+BOOLEAN STDCALL
+HalFlushCommonBuffer (ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3,
+ ULONG Unknown4,
+ ULONG Unknown5,
+ ULONG Unknown6,
+ ULONG Unknown7,
+ ULONG Unknown8)
+{
+ return TRUE;
+}
+
+VOID STDCALL
+HalFreeCommonBuffer (PADAPTER_OBJECT AdapterObject,
+ ULONG Length,
+ PHYSICAL_ADDRESS LogicalAddress,
+ PVOID VirtualAddress,
+ BOOLEAN CacheEnabled)
+{
+ MmFreeContiguousMemory(VirtualAddress);
+}
+
+PADAPTER_OBJECT STDCALL
+HalGetAdapter (PDEVICE_DESCRIPTION DeviceDescription,
+ PULONG NumberOfMapRegisters)
+/*
+ * FUNCTION: Returns a pointer to an adapter object for the DMA device
+ * defined in the device description structure
+ * ARGUMENTS:
+ * DeviceDescription = Structure describing the attributes of the device
+ * NumberOfMapRegisters (OUT) = Returns the maximum number of map
+ * registers the device driver can
+ * allocate for DMA transfer operations
+ * RETURNS: The allocated adapter object on success
+ * NULL on failure
+ * TODO:
+ * Testing
+ */
+{
+ PADAPTER_OBJECT AdapterObject;
+ DWORD ChannelSelect;
+ DWORD Controller;
+ ULONG MaximumLength;
+ BOOLEAN ChannelSetup;
+
+ DPRINT("Entered Function\n");
+
+ /* Validate parameters in device description, and return a pointer to
+ the adapter object for the requested dma channel */
+ if(DeviceDescription->Version != DEVICE_DESCRIPTION_VERSION) {
+ DPRINT("Invalid Adapter version!\n");
+ return NULL;
+ }
+
+ DPRINT("Checking Interface Type: %x \n", DeviceDescription->InterfaceType);
+ if (DeviceDescription->InterfaceType == PCIBus) {
+ if (DeviceDescription->Master == FALSE) {
+ DPRINT("Invalid request!\n");
+ return NULL;
+ }
+ ChannelSetup = FALSE;
+ }
+
+ /* There are only 8 DMA channels on ISA, so any request above this
+ should not get any channel setup */
+ if (DeviceDescription->DmaChannel >= 8) {
+ ChannelSetup = FALSE;
+ }
+
+ /* Channel 4 is Reserved for Chaining, so you cant use it */
+ if (DeviceDescription->DmaChannel == 4 && ChannelSetup) {
+ DPRINT("Invalid request!\n");
+ return NULL;
+ }
+
+ /* Devices that support Scatter/Gather do not need Map Registers */
+ if (DeviceDescription->ScatterGather ||
+ DeviceDescription->InterfaceType == PCIBus) {
+ *NumberOfMapRegisters = 0;
+ }
+
+ /* Check if Extended DMA is available (we're just going to do a random read/write
+ I picked Channel 2 because it's the first Channel in the Register */
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2), 0x2A);
+ if (READ_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaController1Pages.Channel2)) == 0x2A) {
+ HalpEisaDma = TRUE;
+ }
+
+ /* Find out how many Map Registers we need */
+ DPRINT("Setting up Adapter Settings!\n");
+ MaximumLength = DeviceDescription->MaximumLength & 0x7FFFFFFF;
+ *NumberOfMapRegisters = BYTES_TO_PAGES(MaximumLength) + 1;
+
+ /* Set the Channel Selection */
+ ChannelSelect = DeviceDescription->DmaChannel & 0x03;
+
+ /* Get the Controller Setup */
+ Controller = (DeviceDescription->DmaChannel & 0x04) ? 2 : 1;
+
+ /* Get the Adapter Object */
+ if (HalpEisaAdapter[DeviceDescription->DmaChannel] != NULL) {
+
+ /* Already allocated, return it */
+ DPRINT("Getting an Adapter Object from the Cache\n");
+ AdapterObject = HalpEisaAdapter[DeviceDescription->DmaChannel];
+
+ /* Do we need more Map Registers this time? */
+ if ((AdapterObject->NeedsMapRegisters) &&
+ (*NumberOfMapRegisters > AdapterObject->MapRegistersPerChannel)) {
+ AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
+ }
+
+ } else {
+
+ /* We have to allocate a new object! How exciting! */
+ DPRINT("Allocating a new Adapter Object\n");
+ AdapterObject = HalpAllocateAdapterEx(*NumberOfMapRegisters,
+ FALSE,
+ DeviceDescription->Dma32BitAddresses);
+
+ if (AdapterObject == NULL) return NULL;
+
+ HalpEisaAdapter[DeviceDescription->DmaChannel] = AdapterObject;
+
+ if (!*NumberOfMapRegisters) {
+ /* Easy case, no Map Registers needed */
+ AdapterObject->NeedsMapRegisters = FALSE;
+
+ /* If you're the master, you get all you want */
+ if (DeviceDescription->Master) {
+ AdapterObject->MapRegistersPerChannel= *NumberOfMapRegisters;
+ } else {
+ AdapterObject->MapRegistersPerChannel = 1;
+ }
+ } else {
+ /* We Desire Registers */
+ AdapterObject->NeedsMapRegisters = TRUE;
+
+ /* The registers you want */
+ AdapterObject->MapRegistersPerChannel = *NumberOfMapRegisters;
+
+ /* Increase commitment */
+ MasterAdapter->CommittedMapRegisters += *NumberOfMapRegisters;
+ }
+ }
+
+ /* Set up DMA Structure */
+ if (Controller == 1) {
+ AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController1);
+ } else {
+ AdapterObject->AdapterBaseVa = (PVOID)FIELD_OFFSET(EISA_CONTROL, DmaController2);
+ }
+
+ /* Set up Some Adapter Data */
+ DPRINT("Setting up an Adapter Object\n");
+ AdapterObject->IgnoreCount = DeviceDescription->IgnoreCount;
+ AdapterObject->Dma32BitAddresses = DeviceDescription->Dma32BitAddresses;
+ AdapterObject->Dma64BitAddresses = DeviceDescription->Dma64BitAddresses;
+ AdapterObject->ScatterGather = DeviceDescription->ScatterGather;
+ AdapterObject->MasterDevice = DeviceDescription->Master;
+ if (DeviceDescription->InterfaceType != PCIBus) AdapterObject->LegacyAdapter = TRUE;
+
+ /* Everything below is not required if we don't need a channel */
+ if (!ChannelSetup) {
+ DPRINT("Retuning Adapter Object without Channel Setup\n");
+ return AdapterObject;
+ }
+
+ AdapterObject->ChannelNumber = ChannelSelect;
+
+
+ /* Set up the Page Port */
+ if (Controller == 1) {
+ switch (ChannelSelect) {
+
+ case 0:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel0));
+ break;
+ case 1:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel1));
+ break;
+ case 2:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel2));
+ break;
+ case 3:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel3));
+ break;
+ }
+
+ /* Set Controller Number */
+ AdapterObject->AdapterNumber = 1;
+ } else {
+ switch (ChannelSelect) {
+
+ case 1:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel5));
+ break;
+ case 2:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel6));
+ break;
+ case 3:
+ AdapterObject->PagePort = (PUCHAR)(FIELD_OFFSET(DMA_PAGE, Channel7));
+ break;
+ }
+
+ /* Set Controller Number */
+ AdapterObject->AdapterNumber = 2;
+ }
+
+ /* Set up the Extended Register */
+ if (HalpEisaDma) {
+ DMA_EXTENDED_MODE ExtendedMode;
+
+ ExtendedMode.ChannelNumber = ChannelSelect;
+
+ switch (DeviceDescription->DmaSpeed) {
+
+ case Compatible:
+ ExtendedMode.TimingMode = COMPATIBLE_TIMING;
+ break;
+
+ case TypeA:
+ ExtendedMode.TimingMode = TYPE_A_TIMING;
+ break;
+
+ case TypeB:
+ ExtendedMode.TimingMode = TYPE_B_TIMING;
+ break;
+
+ case TypeC:
+ ExtendedMode.TimingMode = BURST_TIMING;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ switch (DeviceDescription->DmaWidth) {
+
+ case Width8Bits:
+ ExtendedMode.TransferSize = B_8BITS;
+ break;
+
+ case Width16Bits:
+ ExtendedMode.TransferSize = B_16BITS;
+ break;
+
+ case Width32Bits:
+ ExtendedMode.TransferSize = B_32BITS;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ if (Controller == 1) {
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode1),
+ *((PUCHAR)&ExtendedMode));
+ } else {
+ WRITE_PORT_UCHAR((PUCHAR)FIELD_OFFSET(EISA_CONTROL, DmaExtendedMode2),
+ *((PUCHAR)&ExtendedMode));
+ }
+ }
+ /* Do 8/16-bit validation */
+ DPRINT("Validating an Adapter Object\n");
+ if (!DeviceDescription->Master) {
+ if ((DeviceDescription->DmaWidth == Width8Bits) && (Controller != 1)) {
+ return NULL; /* 8-bit is only avalable on Controller 1 */
+ } else if (DeviceDescription->DmaWidth == Width16Bits) {
+ if (Controller != 2) {
+ return NULL; /* 16-bit is only avalable on Controller 2 */
+ } else {
+ AdapterObject->Width16Bits = TRUE;
+ }
+ }
+ }
+ UCHAR DmaMode;
+ DPRINT("Final DMA Request Mode Setting of the Adapter Object\n");
+ /* Set the DMA Request Modes */
+ if (DeviceDescription->Master) {
+ /* This is a cascade request */
+ ((PDMA_MODE)&DmaMode)->RequestMode = CASCADE_REQUEST_MODE;
+
+ /* Send the request */
+ if (AdapterObject->AdapterNumber == 1) {
+ /* Set the Request Data */
+ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
+ AdapterObject->AdapterMode);
+
+ /* Unmask DMA Channel */
+ WRITE_PORT_UCHAR(&((PDMA1_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ } else {
+ /* Set the Request Data */
+ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->Mode,
+ AdapterObject->AdapterMode);
+
+ /* Unmask DMA Channel */
+ WRITE_PORT_UCHAR(&((PDMA2_CONTROL)AdapterObject->AdapterBaseVa)->SingleMask,
+ AdapterObject->ChannelNumber | DMA_CLEARMASK);
+ }
+ } else if (DeviceDescription->DemandMode) {
+ /* This is a Demand request */
+ ((PDMA_MODE)&DmaMode)->RequestMode = DEMAND_REQUEST_MODE;
+ } else {
+ /* Normal Request */
+ ((PDMA_MODE)&DmaMode)->RequestMode = SINGLE_REQUEST_MODE;
+ }
+
+ /* Auto Initialize Enabled or Not*/
+ ((PDMA_MODE)&DmaMode)->AutoInitialize = DeviceDescription->AutoInitialize;
+ AdapterObject->AdapterMode = DmaMode;
+ return AdapterObject;
+}
+
+ULONG STDCALL
+HalReadDmaCounter (PADAPTER_OBJECT AdapterObject)
+{
+ KIRQL OldIrql;
+ ULONG Count;
+
+ KeAcquireSpinLock(&AdapterObject->MasterAdapter->SpinLock, &OldIrql);
+
+ /* Send the Request to the specific controller */
+ if (AdapterObject->AdapterNumber == 1) {
+
+ /* Set this for Ease */
+ PDMA1_CONTROL DmaControl1 = AdapterObject->AdapterBaseVa;
+
+ /* Send Reset */
+ WRITE_PORT_UCHAR(&DmaControl1->ClearBytePointer, 0);
+
+ /* Read Count */
+ Count = READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount);
+ Count |= READ_PORT_UCHAR(&DmaControl1->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+
+ } else {
+
+ /* Set this for Ease */
+ PDMA2_CONTROL DmaControl2 = AdapterObject->AdapterBaseVa;
+
+ /* Send Reset */
+ WRITE_PORT_UCHAR(&DmaControl2->ClearBytePointer, 0);
+
+ /* Read Count */
+ Count = READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount);
+ Count |= READ_PORT_UCHAR(&DmaControl2->DmaAddressCount
+ [AdapterObject->ChannelNumber].DmaBaseCount) << 8;
+ }
+
+ /* Play around with the count (add bias and multiply by 2 if 16-bit DMA) */
+ Count ++;
+ if (AdapterObject->Width16Bits) Count *=2 ;
+
+ KeReleaseSpinLock(&AdapterObject->MasterAdapter->SpinLock, OldIrql);
+
+ /* Return it */
+ return Count;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N drive.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ drive.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,31 @@
+/* $Id: drive.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/x86/drive.c
+ * PURPOSE: Drive letter assignment
+ * PROGRAMMER:
+ * UPDATE HISTORY:
+ * 2000-03-25
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID STDCALL
+IoAssignDriveLetters(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PSTRING NtDeviceName,
+ OUT PUCHAR NtSystemPath,
+ OUT PSTRING NtSystemPathString)
+{
+ HalIoAssignDriveLetters(LoaderBlock,
+ NtDeviceName,
+ NtSystemPath,
+ NtSystemPathString);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N enum.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ enum.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,24 @@
+/* $Id: enum.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/enum.c
+ * PURPOSE: Motherboard device enumerator
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * Created 01/05/2001
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+VOID
+HalpStartEnumerator (VOID)
+{
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N fmutex.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ fmutex.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,53 @@
+/* $Id: fmutex.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/fmutex.c
+ * PURPOSE: Implements fast mutexes
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * Created 09/06/2000
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+VOID FASTCALL
+ExAcquireFastMutex (PFAST_MUTEX FastMutex)
+{
+ KeEnterCriticalRegion();
+ ExAcquireFastMutexUnsafe(FastMutex);
+}
+
+
+VOID FASTCALL
+ExReleaseFastMutex (PFAST_MUTEX FastMutex)
+{
+ ExReleaseFastMutexUnsafe(FastMutex);
+ KeLeaveCriticalRegion();
+}
+
+
+BOOLEAN FASTCALL
+ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex)
+{
+ KeEnterCriticalRegion();
+ if (InterlockedExchange(&FastMutex->Count, 0) == 1)
+ {
+ FastMutex->Owner = KeGetCurrentThread();
+ return(TRUE);
+ }
+ else
+ {
+ KeLeaveCriticalRegion();
+ return(FALSE);
+ }
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N halinit.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit.c 13 Dec 2004 16:18:23 -0000 1.3.2.1
@@ -0,0 +1,66 @@
+/* $Id: halinit.c,v 1.3.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS *****************************************************************/
+
+PVOID HalpZeroPageMapping = NULL;
+HALP_HOOKS HalpHooks;
+
+/* FUNCTIONS ***************************************************************/
+
+NTSTATUS
+STDCALL
+DriverEntry(
+ PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
+{
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN STDCALL
+HalInitSystem (ULONG BootPhase,
+ PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ if (BootPhase == 0)
+ {
+ RtlZeroMemory(&HalpHooks, sizeof(HALP_HOOKS));
+ HalpInitPhase0();
+ }
+ else if (BootPhase == 1)
+ {
+ /* Initialize display and make the screen black */
+ HalInitializeDisplay (LoaderBlock);
+ HalpInitBusHandlers();
+ HalpInitDma();
+
+ /* Enumerate the devices on the motherboard */
+ HalpStartEnumerator();
+ }
+ else if (BootPhase == 2)
+ {
+ /* Go to blue screen */
+ HalClearDisplay (0x17); /* grey on blue */
+
+ HalpZeroPageMapping = MmMapIoSpace((LARGE_INTEGER)0LL, PAGE_SIZE, MmNonCached);
+ }
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N ipi.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ipi.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,26 @@
+/* $Id: ipi.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/ipi.c
+ * PURPOSE: Miscellaneous hardware functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+ DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N irql.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ irql.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,479 @@
+/* $Id: irql.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/irql.c
+ * PURPOSE: Implements IRQLs
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <ntos/minmax.h>
+#include <hal.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+/*
+ * FIXME: Use EISA_CONTROL STRUCTURE INSTEAD OF HARD-CODED OFFSETS
+*/
+
+typedef union
+{
+ USHORT both;
+ struct
+ {
+ BYTE master;
+ BYTE slave;
+ };
+}
+PIC_MASK;
+
+/*
+ * PURPOSE: - Mask for HalEnableSystemInterrupt and HalDisableSystemInterrupt
+ * - At startup enable timer and cascade
+ */
+#if defined(__GNUC__)
+static PIC_MASK pic_mask = {.both = 0xFFFA};
+#else
+static PIC_MASK pic_mask = { 0xFFFA };
+#endif
+
+
+/*
+ * PURPOSE: Mask for disabling of acknowledged interrupts
+ */
+#if defined(__GNUC__)
+static PIC_MASK pic_mask_intr = {.both = 0x0000};
+#else
+static PIC_MASK pic_mask_intr = { 0 };
+#endif
+
+static ULONG HalpPendingInterruptCount[NR_IRQS];
+
+#define DIRQL_TO_IRQ(x) (PROFILE_LEVEL - x)
+#define IRQ_TO_DIRQL(x) (PROFILE_LEVEL - x)
+
+VOID STDCALL
+KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
+
+/* FUNCTIONS ****************************************************************/
+
+KIRQL STDCALL KeGetCurrentIrql (VOID)
+/*
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
+ */
+{
+ return(KeGetCurrentKPCR()->Irql);
+}
+
+VOID HalpInitPICs(VOID)
+{
+ memset(HalpPendingInterruptCount, 0, sizeof(HalpPendingInterruptCount));
+
+ /* Initialization sequence */
+ WRITE_PORT_UCHAR((PUCHAR)0x20, 0x11);
+ WRITE_PORT_UCHAR((PUCHAR)0xa0, 0x11);
+ /* Start of hardware irqs (0x24) */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, IRQ_BASE);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, IRQ_BASE + 8);
+ /* 8259-1 is master */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, 0x4);
+ /* 8259-2 is slave */
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x2);
+ /* 8086 mode */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, 0x1);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, 0x1);
+ /* Enable interrupts */
+ WRITE_PORT_UCHAR((PUCHAR)0x21, pic_mask.master);
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, pic_mask.slave);
+
+ /* We can now enable interrupts */
+ Ki386EnableInterrupts();
+}
+
+VOID HalpEndSystemInterrupt(KIRQL Irql)
+/*
+ * FUNCTION: Enable all irqs with higher priority.
+ */
+{
+ ULONG flags;
+ const USHORT mask[] =
+ {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0xc000, 0xe000, 0xf000,
+ 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0,
+ 0xfff8, 0xfffc, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
+ };
+
+ /* Interrupts should be disable while enabling irqs of both pics */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ pic_mask_intr.both &= mask[Irql];
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+}
+
+VOID STATIC
+HalpExecuteIrqs(KIRQL NewIrql)
+{
+ ULONG IrqLimit, i;
+
+ IrqLimit = min(PROFILE_LEVEL - NewIrql, NR_IRQS);
+
+ /*
+ * For each irq if there have been any deferred interrupts then now
+ * dispatch them.
+ */
+ for (i = 0; i < IrqLimit; i++)
+ {
+ if (HalpPendingInterruptCount[i] > 0)
+ {
+ KeGetCurrentKPCR()->Irql = (KIRQL)IRQ_TO_DIRQL(i);
+
+ while (HalpPendingInterruptCount[i] > 0)
+ {
+ /*
+ * For each deferred interrupt execute all the handlers at DIRQL.
+ */
+ HalpPendingInterruptCount[i]--;
+ KiInterruptDispatch2(i + IRQ_BASE, NewIrql);
+ }
+ KeGetCurrentKPCR()->Irql--;
+ HalpEndSystemInterrupt(KeGetCurrentKPCR()->Irql);
+ }
+ }
+
+}
+
+VOID STATIC
+HalpLowerIrql(KIRQL NewIrql)
+{
+ if (NewIrql >= PROFILE_LEVEL)
+ {
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ return;
+ }
+ HalpExecuteIrqs(NewIrql);
+ if (NewIrql >= DISPATCH_LEVEL)
+ {
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ return;
+ }
+ KeGetCurrentKPCR()->Irql = DISPATCH_LEVEL;
+ if (KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST])
+ {
+ KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = FALSE;
+ KiDispatchInterrupt();
+ }
+ KeGetCurrentKPCR()->Irql = APC_LEVEL;
+ if (NewIrql == APC_LEVEL)
+ {
+ return;
+ }
+ if (KeGetCurrentThread() != NULL &&
+ KeGetCurrentThread()->ApcState.KernelApcPending)
+ {
+ KiDeliverApc(KernelMode, NULL, NULL);
+ }
+ KeGetCurrentKPCR()->Irql = PASSIVE_LEVEL;
+}
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+VOID FASTCALL
+KfLowerIrql (KIRQL NewIrql)
+{
+ DPRINT("KfLowerIrql(NewIrql %d)\n", NewIrql);
+
+ if (NewIrql > KeGetCurrentKPCR()->Irql)
+ {
+ DbgPrint ("(%s:%d) NewIrql %x CurrentIrql %x\n",
+ __FILE__, __LINE__, NewIrql, KeGetCurrentKPCR()->Irql);
+ KEBUGCHECK(0);
+ for(;;);
+ }
+
+ HalpLowerIrql(NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ */
+
+VOID STDCALL
+KeLowerIrql (KIRQL NewIrql)
+{
+ KfLowerIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ *
+ * RETURN VALUE
+ * previous irq level
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+
+KIRQL FASTCALL
+KfRaiseIrql (KIRQL NewIrql)
+{
+ KIRQL OldIrql;
+
+ DPRINT("KfRaiseIrql(NewIrql %d)\n", NewIrql);
+
+ if (NewIrql < KeGetCurrentKPCR()->Irql)
+ {
+ DbgPrint ("%s:%d CurrentIrql %x NewIrql %x\n",
+ __FILE__,__LINE__,KeGetCurrentKPCR()->Irql,NewIrql);
+ KEBUGCHECK (0);
+ for(;;);
+ }
+
+ OldIrql = KeGetCurrentKPCR()->Irql;
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ return OldIrql;
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ * OldIrql (OUT) = Caller supplied storage for the previous irql
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+VOID STDCALL
+KeRaiseIrql (KIRQL NewIrql,
+ PKIRQL OldIrql)
+{
+ *OldIrql = KfRaiseIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+ return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+ return KfRaiseIrql (CLOCK2_LEVEL);
+}
+
+
+BOOLEAN STDCALL
+HalBeginSystemInterrupt (ULONG Vector,
+ KIRQL Irql,
+ PKIRQL OldIrql)
+{
+ ULONG irq;
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+ {
+ return(FALSE);
+ }
+ irq = Vector - IRQ_BASE;
+ pic_mask_intr.both |= ((1 << irq) & 0xfffe); // do not disable the timer interrupt
+
+ if (irq < 8)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+ WRITE_PORT_UCHAR((PUCHAR)0x20, 0x20);
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ /* Send EOI to the PICs */
+ WRITE_PORT_UCHAR((PUCHAR)0x20,0x20);
+ WRITE_PORT_UCHAR((PUCHAR)0xa0,0x20);
+ }
+
+ if (KeGetCurrentKPCR()->Irql >= Irql)
+ {
+ HalpPendingInterruptCount[irq]++;
+ return(FALSE);
+ }
+ *OldIrql = KeGetCurrentKPCR()->Irql;
+ KeGetCurrentKPCR()->Irql = Irql;
+
+ return(TRUE);
+}
+
+
+VOID STDCALL HalEndSystemInterrupt (KIRQL Irql, ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+ HalpLowerIrql(Irql);
+ HalpEndSystemInterrupt(Irql);
+}
+
+BOOLEAN
+STDCALL
+HalDisableSystemInterrupt(
+ ULONG Vector,
+ KIRQL Irql)
+{
+ ULONG irq;
+
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+ return FALSE;
+
+ irq = Vector - IRQ_BASE;
+ pic_mask.both |= (1 << irq);
+ if (irq < 8)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.slave));
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+STDCALL
+HalEnableSystemInterrupt(
+ ULONG Vector,
+ KIRQL Irql,
+ KINTERRUPT_MODE InterruptMode)
+{
+ ULONG irq;
+
+ if (Vector < IRQ_BASE || Vector >= IRQ_BASE + NR_IRQS)
+ return FALSE;
+
+ irq = Vector - IRQ_BASE;
+ pic_mask.both &= ~(1 << irq);
+ if (irq < 8)
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0x21, (UCHAR)(pic_mask.master|pic_mask_intr.master));
+ }
+ else
+ {
+ WRITE_PORT_UCHAR((PUCHAR)0xa1, (UCHAR)(pic_mask.slave|pic_mask_intr.slave));
+ }
+
+ return TRUE;
+}
+
+
+VOID FASTCALL
+HalRequestSoftwareInterrupt(
+ IN KIRQL Request)
+{
+ switch (Request)
+ {
+ case APC_LEVEL:
+ KeGetCurrentKPCR()->HalReserved[HAL_APC_REQUEST] = TRUE;
+ break;
+
+ case DISPATCH_LEVEL:
+ KeGetCurrentKPCR()->HalReserved[HAL_DPC_REQUEST] = TRUE;
+ break;
+
+ default:
+ KEBUGCHECK(0);
+ }
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N isa.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ isa.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,78 @@
+/* $Id: isa.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/isa.c
+ * PURPOSE: Interfaces to the ISA bus
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * 05/06/98: Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOL HalIsaProbe(VOID)
+/*
+ * FUNCTION: Probes for an ISA bus
+ * RETURNS: True if detected
+ * NOTE: Since ISA is the default we are called last and always return
+ * true
+ */
+{
+ DbgPrint("Assuming ISA bus\n");
+
+ /*
+ * Probe for plug and play support
+ */
+ return(TRUE);
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ BOOLEAN Result;
+
+ Result = HalTranslateBusAddress(PCIBus,
+ BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress);
+ if (Result != FALSE)
+ return Result;
+
+ Result = HalTranslateBusAddress(Internal,
+ BusNumber,
+ BusAddress,
+ AddressSpace,
+ TranslatedAddress);
+ return Result;
+}
+
+ULONG STDCALL
+HalpGetIsaInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+/* EOF */
reactos/hal/halx86/generic
diff -N kdbg.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kdbg.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,548 @@
+/* $Id: kdbg.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/kdbg.c
+ * PURPOSE: Serial i/o functions for the kernel debugger.
+ * PROGRAMMER: Emanuele Aliberti
+ * Eric Kohl
+ * UPDATE HISTORY:
+ * Created 05/09/99
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+#define DEFAULT_BAUD_RATE 19200
+
+
+/* MACROS *******************************************************************/
+
+#define SER_RBR(x) ((x)+0)
+#define SER_THR(x) ((x)+0)
+#define SER_DLL(x) ((x)+0)
+#define SER_IER(x) ((x)+1)
+#define SR_IER_ERDA 0x01
+#define SR_IER_ETHRE 0x02
+#define SR_IER_ERLSI 0x04
+#define SR_IER_EMS 0x08
+#define SR_IER_ALL 0x0F
+#define SER_DLM(x) ((x)+1)
+#define SER_IIR(x) ((x)+2)
+#define SER_FCR(x) ((x)+2)
+#define SR_FCR_ENABLE_FIFO 0x01
+#define SR_FCR_CLEAR_RCVR 0x02
+#define SR_FCR_CLEAR_XMIT 0x04
+#define SER_LCR(x) ((x)+3)
+#define SR_LCR_CS5 0x00
+#define SR_LCR_CS6 0x01
+#define SR_LCR_CS7 0x02
+#define SR_LCR_CS8 0x03
+#define SR_LCR_ST1 0x00
+#define SR_LCR_ST2 0x04
+#define SR_LCR_PNO 0x00
+#define SR_LCR_POD 0x08
+#define SR_LCR_PEV 0x18
+#define SR_LCR_PMK 0x28
+#define SR_LCR_PSP 0x38
+#define SR_LCR_BRK 0x40
+#define SR_LCR_DLAB 0x80
+#define SER_MCR(x) ((x)+4)
+#define SR_MCR_DTR 0x01
+#define SR_MCR_RTS 0x02
+#define SR_MCR_OUT1 0x04
+#define SR_MCR_OUT2 0x08
+#define SR_MCR_LOOP 0x10
+#define SER_LSR(x) ((x)+5)
+#define SR_LSR_DR 0x01
+#define SR_LSR_TBE 0x20
+#define SER_MSR(x) ((x)+6)
+#define SR_MSR_CTS 0x10
+#define SR_MSR_DSR 0x20
+#define SER_SCR(x) ((x)+7)
+
+
+/* GLOBAL VARIABLES *********************************************************/
+
+ULONG EXPORTED KdComPortInUse = 0;
+
+
+/* STATIC VARIABLES *********************************************************/
+
+static ULONG ComPort = 0;
+static ULONG BaudRate = 0;
+static PUCHAR PortBase = (PUCHAR)0;
+
+/* The com port must only be initialized once! */
+static BOOLEAN PortInitialized = FALSE;
+
+
+/* STATIC FUNCTIONS *********************************************************/
+
+static BOOLEAN
+KdpDoesComPortExist (PUCHAR BaseAddress)
+{
+ BOOLEAN found;
+ BYTE mcr;
+ BYTE msr;
+
+ found = FALSE;
+
+ /* save Modem Control Register (MCR) */
+ mcr = READ_PORT_UCHAR (SER_MCR(BaseAddress));
+
+ /* enable loop mode (set Bit 4 of the MCR) */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+ /* clear all modem output bits */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x10);
+
+ /* read the Modem Status Register */
+ msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+ /*
+ * the upper nibble of the MSR (modem output bits) must be
+ * equal to the lower nibble of the MCR (modem input bits)
+ */
+ if ((msr & 0xF0) == 0x00)
+ {
+ /* set all modem output bits */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), 0x1F);
+
+ /* read the Modem Status Register */
+ msr = READ_PORT_UCHAR (SER_MSR(BaseAddress));
+
+ /*
+ * the upper nibble of the MSR (modem output bits) must be
+ * equal to the lower nibble of the MCR (modem input bits)
+ */
+ if ((msr & 0xF0) == 0xF0)
+ {
+ /*
+ * setup a resonable state for the port:
+ * enable fifo and clear recieve/transmit buffers
+ */
+ WRITE_PORT_UCHAR (SER_FCR(BaseAddress),
+ (SR_FCR_ENABLE_FIFO | SR_FCR_CLEAR_RCVR | SR_FCR_CLEAR_XMIT));
+ WRITE_PORT_UCHAR (SER_FCR(BaseAddress), 0);
+ READ_PORT_UCHAR (SER_RBR(BaseAddress));
+ WRITE_PORT_UCHAR (SER_IER(BaseAddress), 0);
+ found = TRUE;
+ }
+ }
+
+ /* restore MCR */
+ WRITE_PORT_UCHAR (SER_MCR(BaseAddress), mcr);
+
+ return (found);
+}
+
+
+/* FUNCTIONS ****************************************************************/
+
+/* HAL.KdPortInitialize */
+BOOLEAN
+STDCALL
+KdPortInitialize (
+ PKD_PORT_INFORMATION PortInformation,
+ DWORD Unknown1,
+ DWORD Unknown2
+ )
+{
+ ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ char buffer[80];
+ ULONG divisor;
+ BYTE lcr;
+
+ if (PortInitialized == FALSE)
+ {
+ if (PortInformation->BaudRate != 0)
+ {
+ BaudRate = PortInformation->BaudRate;
+ }
+ else
+ {
+ BaudRate = DEFAULT_BAUD_RATE;
+ }
+
+ if (PortInformation->ComPort == 0)
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[2]))
+ {
+ PortBase = (PUCHAR)BaseArray[2];
+ ComPort = 2;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+ PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else if (KdpDoesComPortExist ((PUCHAR)BaseArray[1]))
+ {
+ PortBase = (PUCHAR)BaseArray[1];
+ ComPort = 1;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+ PortInformation->ComPort = ComPort;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: No COM port found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+ {
+ PortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+ ComPort = PortInformation->ComPort;
+ PortInformation->BaseAddress = (ULONG)PortBase;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ ComPort,
+ (ULONG)PortBase);
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: No serial port found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+
+ PortInitialized = TRUE;
+ }
+
+ /*
+ * set baud rate and data format (8N1)
+ */
+
+ /* turn on DTR and RTS */
+ WRITE_PORT_UCHAR (SER_MCR(PortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+ /* set DLAB */
+ lcr = READ_PORT_UCHAR (SER_LCR(PortBase)) | SR_LCR_DLAB;
+ WRITE_PORT_UCHAR (SER_LCR(PortBase), lcr);
+
+ /* set baud rate */
+ divisor = 115200 / BaudRate;
+ WRITE_PORT_UCHAR (SER_DLL(PortBase), (UCHAR)(divisor & 0xff));
+ WRITE_PORT_UCHAR (SER_DLM(PortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+ /* reset DLAB and set 8N1 format */
+ WRITE_PORT_UCHAR (SER_LCR(PortBase),
+ SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+ /* read junk out of the RBR */
+ lcr = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+ /*
+ * set global info
+ */
+ KdComPortInUse = (ULONG)PortBase;
+
+ /*
+ * print message to blue screen
+ */
+ sprintf (buffer,
+ "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+ ComPort,
+ (ULONG)PortBase,
+ BaudRate);
+
+ HalDisplayString (buffer);
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortInitializeEx */
+BOOLEAN
+STDCALL
+KdPortInitializeEx (
+ PKD_PORT_INFORMATION PortInformation,
+ DWORD Unknown1,
+ DWORD Unknown2
+ )
+{
+ ULONG BaseArray[5] = {0, 0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ PUCHAR ComPortBase;
+ char buffer[80];
+ ULONG divisor;
+ BYTE lcr;
+
+ if (PortInformation->BaudRate == 0)
+ {
+ PortInformation->BaudRate = DEFAULT_BAUD_RATE;
+ }
+
+ if (PortInformation->ComPort == 0)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (KdpDoesComPortExist ((PUCHAR)BaseArray[PortInformation->ComPort]))
+ {
+ ComPortBase = (PUCHAR)BaseArray[PortInformation->ComPort];
+ PortInformation->BaseAddress = (ULONG)ComPortBase;
+#ifndef NDEBUG
+ sprintf (buffer,
+ "\nSerial port COM%ld found at 0x%lx\n",
+ PortInformation->ComPort,
+ (ULONG)ComPortBase];
+ HalDisplayString (buffer);
+#endif /* NDEBUG */
+ }
+ else
+ {
+ sprintf (buffer,
+ "\nKernel Debugger: Serial port not found!!!\n\n");
+ HalDisplayString (buffer);
+ return FALSE;
+ }
+ }
+
+ /*
+ * set baud rate and data format (8N1)
+ */
+
+ /* turn on DTR and RTS */
+ WRITE_PORT_UCHAR (SER_MCR(ComPortBase), SR_MCR_DTR | SR_MCR_RTS);
+
+ /* set DLAB */
+ lcr = READ_PORT_UCHAR (SER_LCR(ComPortBase)) | SR_LCR_DLAB;
+ WRITE_PORT_UCHAR (SER_LCR(ComPortBase), lcr);
+
+ /* set baud rate */
+ divisor = 115200 / PortInformation->BaudRate;
+ WRITE_PORT_UCHAR (SER_DLL(ComPortBase), (UCHAR)(divisor & 0xff));
+ WRITE_PORT_UCHAR (SER_DLM(ComPortBase), (UCHAR)((divisor >> 8) & 0xff));
+
+ /* reset DLAB and set 8N1 format */
+ WRITE_PORT_UCHAR (SER_LCR(ComPortBase),
+ SR_LCR_CS8 | SR_LCR_ST1 | SR_LCR_PNO);
+
+ /* read junk out of the RBR */
+ lcr = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+#ifndef NDEBUG
+
+ /*
+ * print message to blue screen
+ */
+ sprintf (buffer,
+ "\nKernel Debugger: COM%ld (Port 0x%lx) BaudRate %ld\n\n",
+ PortInformation->ComPort,
+ (ULONG)ComPortBase,
+ PortInformation->BaudRate);
+
+ HalDisplayString (buffer);
+
+#endif /* NDEBUG */
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortGetByte */
+BOOLEAN
+STDCALL
+KdPortGetByte (
+ PUCHAR ByteRecieved
+ )
+{
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ if ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR))
+ {
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* HAL.KdPortGetByteEx */
+BOOLEAN
+STDCALL
+KdPortGetByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ PUCHAR ByteRecieved
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ if ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR))
+ {
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/* HAL.KdPortPollByte */
+BOOLEAN
+STDCALL
+KdPortPollByte (
+ PUCHAR ByteRecieved
+ )
+{
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_DR) == 0)
+ ;
+
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(PortBase));
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortPollByteEx */
+BOOLEAN
+STDCALL
+KdPortPollByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ PUCHAR ByteRecieved
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_DR) == 0)
+ ;
+
+ *ByteRecieved = READ_PORT_UCHAR (SER_RBR(ComPortBase));
+
+ return TRUE;
+}
+
+
+
+
+/* HAL.KdPortPutByte */
+VOID
+STDCALL
+KdPortPutByte (
+ UCHAR ByteToSend
+ )
+{
+ if (PortInitialized == FALSE)
+ return;
+
+ while ((READ_PORT_UCHAR (SER_LSR(PortBase)) & SR_LSR_TBE) == 0)
+ ;
+
+ WRITE_PORT_UCHAR (SER_THR(PortBase), ByteToSend);
+}
+
+/* HAL.KdPortPutByteEx */
+VOID
+STDCALL
+KdPortPutByteEx (
+ PKD_PORT_INFORMATION PortInformation,
+ UCHAR ByteToSend
+ )
+{
+ PUCHAR ComPortBase = (PUCHAR)PortInformation->BaseAddress;
+
+ while ((READ_PORT_UCHAR (SER_LSR(ComPortBase)) & SR_LSR_TBE) == 0)
+ ;
+
+ WRITE_PORT_UCHAR (SER_THR(ComPortBase), ByteToSend);
+}
+
+
+/* HAL.KdPortRestore */
+VOID
+STDCALL
+KdPortRestore (
+ VOID
+ )
+{
+}
+
+
+/* HAL.KdPortSave */
+VOID
+STDCALL
+KdPortSave (
+ VOID
+ )
+{
+}
+
+
+/* HAL.KdPortDisableInterrupts */
+BOOLEAN
+STDCALL
+KdPortDisableInterrupts()
+{
+ UCHAR ch;
+
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+ ch &= (~(SR_MCR_OUT1 | SR_MCR_OUT2));
+ WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+ ch = READ_PORT_UCHAR (SER_IER (PortBase));
+ ch &= (~SR_IER_ALL);
+ WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+ return TRUE;
+}
+
+
+/* HAL.KdPortEnableInterrupts */
+BOOLEAN
+STDCALL
+KdPortEnableInterrupts()
+{
+ UCHAR ch;
+
+ if (PortInitialized == FALSE)
+ return FALSE;
+
+ ch = READ_PORT_UCHAR (SER_IER (PortBase));
+ ch &= (~SR_IER_ALL);
+ ch |= SR_IER_ERDA;
+ WRITE_PORT_UCHAR (SER_IER (PortBase), ch);
+
+ ch = READ_PORT_UCHAR (SER_MCR (PortBase));
+ ch &= (~SR_MCR_LOOP);
+ ch |= (SR_MCR_OUT1 | SR_MCR_OUT2);
+ WRITE_PORT_UCHAR (SER_MCR (PortBase), ch);
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N mca.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mca.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,82 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2002 ReactOS Team
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: mca.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mca.c
+ * PURPOSE: Interfaces to the MicroChannel bus
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/*
+ * TODO:
+ * What Adapter ID is read from an empty slot?
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetMicroChannelData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PCM_MCA_POS_DATA PosData = (PCM_MCA_POS_DATA)Buffer;
+
+ DPRINT("HalpGetMicroChannelData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((BusNumber != 0) ||
+ (SlotNumber == 0) || (SlotNumber > 8) ||
+ (Length < sizeof(CM_MCA_POS_DATA)))
+ return(0);
+
+ /* Enter Setup-Mode for given slot */
+ WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)(((UCHAR)(SlotNumber - 1) & 0x07) | 0x08));
+
+ /* Read POS data */
+ PosData->AdapterId = (READ_PORT_UCHAR((PUCHAR)0x101) << 8) +
+ READ_PORT_UCHAR((PUCHAR)0x100);
+ PosData->PosData1 = READ_PORT_UCHAR((PUCHAR)0x102);
+ PosData->PosData2 = READ_PORT_UCHAR((PUCHAR)0x103);
+ PosData->PosData3 = READ_PORT_UCHAR((PUCHAR)0x104);
+ PosData->PosData4 = READ_PORT_UCHAR((PUCHAR)0x105);
+
+ /* Leave Setup-Mode for given slot */
+ WRITE_PORT_UCHAR((PUCHAR)0x96, (UCHAR)((UCHAR)(SlotNumber - 1) & 0x07));
+
+ return(sizeof(CM_MCA_POS_DATA));
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N misc.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ misc.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,69 @@
+/* $Id: misc.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/misc.c
+ * PURPOSE: Miscellaneous hardware functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalHandleNMI(ULONG Unused)
+{
+ UCHAR ucStatus;
+
+ ucStatus = READ_PORT_UCHAR((PUCHAR) 0x61);
+
+ HalDisplayString ("\n*** Hardware Malfunction\n\n");
+ HalDisplayString ("Call your hardware vendor for support\n\n");
+
+ if (ucStatus & 0x80)
+ HalDisplayString ("NMI: Parity Check / Memory Parity Error\n");
+
+ if (ucStatus & 0x40)
+ HalDisplayString ("NMI: Channel Check / IOCHK\n");
+
+ HalDisplayString ("\n*** The system has halted ***\n");
+ KeEnterKernelDebugger ();
+}
+
+
+VOID STDCALL
+HalProcessorIdle(VOID)
+{
+#if 1
+ Ki386EnableInterrupts();
+ Ki386HaltProcessor();
+#else
+
+#endif
+}
+
+ULONG FASTCALL
+HalSystemVectorDispatchEntry (
+ ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3
+ )
+{
+ return 0;
+}
+
+
+VOID STDCALL
+KeFlushWriteBuffer(VOID)
+{
+ return;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N pci.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pci.c 13 Dec 2004 16:18:23 -0000 1.2.2.1
@@ -0,0 +1,816 @@
+/* $Id: pci.c,v 1.2.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/pci.c
+ * PURPOSE: Interfaces to the PCI bus
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 05/06/1998: Created
+ * 17/08/2000: Added preliminary pci bus scanner
+ * 13/06/2001: Implemented access to pci configuration space
+ */
+
+/*
+ * NOTES: Sections copied from the Linux pci support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* MACROS ******************************************************************/
+
+/* FIXME These are also defined in drivers/bus/pci/pcidef.h.
+ Maybe put PCI definitions in a central include file??? */
+
+/* access type 1 macros */
+#define CONFIG_CMD(bus, dev_fn, where) \
+ (0x80000000 | (((ULONG)(bus)) << 16) | (((dev_fn) & 0x1F) << 11) | (((dev_fn) & 0xE0) << 3) | ((where) & ~3))
+
+/* access type 2 macros */
+#define IOADDR(dev_fn, where) \
+ (0xC000 | (((dev_fn) & 0x1F) << 8) | (where))
+#define FUNC(dev_fn) \
+ ((((dev_fn) & 0xE0) >> 4) | 0xf0)
+
+#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
+#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+/* bit 1 is reserved if address_space = 1 */
+
+
+/* GLOBALS ******************************************************************/
+
+#define TAG_PCI TAG('P', 'C', 'I', 'H')
+
+static ULONG BusConfigType = 0; /* undetermined config type */
+static KSPIN_LOCK PciLock;
+
+/* FUNCTIONS ****************************************************************/
+
+static NTSTATUS
+ReadPciConfigUchar(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ PUCHAR Value)
+{
+ KIRQL oldIrql;
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ *Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ *Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+ReadPciConfigUshort(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ PUSHORT Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 1) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ *Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2));
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ *Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+ReadPciConfigUlong(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ PULONG Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 3) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ *Value = READ_PORT_ULONG((PULONG)0xCFC);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ *Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUchar(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ UCHAR Value)
+{
+ KIRQL oldIrql;
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUshort(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ USHORT Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 1) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 2), Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS
+WritePciConfigUlong(UCHAR Bus,
+ UCHAR Slot,
+ UCHAR Offset,
+ ULONG Value)
+{
+ KIRQL oldIrql;
+
+ if ((Offset & 3) != 0)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ switch (BusConfigType)
+ {
+ case 1:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
+ WRITE_PORT_ULONG((PULONG)0xCFC, Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+
+ case 2:
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, (UCHAR)FUNC(Slot));
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
+ WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+static ULONG STDCALL
+HalpGetPciData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PVOID Ptr = Buffer;
+ ULONG Address = Offset;
+ ULONG Len = Length;
+ ULONG Vendor;
+ UCHAR HeaderType;
+
+ DPRINT("HalpGetPciData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((Length == 0) || (BusConfigType == 0))
+ return 0;
+
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ {
+ if (BusNumber == 0 && Offset == 0 && Length >= 2)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+
+ /* 0E=PCI_HEADER_TYPE */
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x0E,
+ &HeaderType);
+ if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
+ {
+ if (Offset == 0 && Length >= 2)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ {
+ if (BusNumber == 0 && Offset == 0 && Length >= 2)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+
+ if ((Address & 1) && (Len >= 1))
+ {
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ if ((Address & 2) && (Len >= 2))
+ {
+ ReadPciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ while (Len >= 4)
+ {
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 4;
+ Address += 4;
+ Len -= 4;
+ }
+
+ if (Len >= 2)
+ {
+ ReadPciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ if (Len >= 1)
+ {
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ return Length - Len;
+}
+
+
+static ULONG STDCALL
+HalpSetPciData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PVOID Ptr = Buffer;
+ ULONG Address = Offset;
+ ULONG Len = Length;
+ ULONG Vendor;
+ UCHAR HeaderType;
+
+ DPRINT("HalpSetPciData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((Length == 0) || (BusConfigType == 0))
+ return 0;
+
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ return 0;
+
+
+ /* 0E=PCI_HEADER_TYPE */
+ ReadPciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)(SlotNumber & 0x1F),
+ 0x0E,
+ &HeaderType);
+ if (((HeaderType & PCI_MULTIFUNCTION) == 0) && ((SlotNumber & 0xE0) != 0))
+ return 0;
+
+ ReadPciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ 0x00,
+ &Vendor);
+ /* some broken boards return 0 if a slot is empty: */
+ if (Vendor == 0xFFFFFFFF || Vendor == 0)
+ return 0;
+
+ if ((Address & 1) && (Len >= 1))
+ {
+ WritePciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUCHAR)Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ if ((Address & 2) && (Len >= 2))
+ {
+ WritePciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUSHORT)Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ while (Len >= 4)
+ {
+ WritePciConfigUlong((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PULONG)Ptr);
+ Ptr = (char*)Ptr + 4;
+ Address += 4;
+ Len -= 4;
+ }
+
+ if (Len >= 2)
+ {
+ WritePciConfigUshort((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUSHORT)Ptr);
+ Ptr = (char*)Ptr + 2;
+ Address += 2;
+ Len -= 2;
+ }
+
+ if (Len >= 1)
+ {
+ WritePciConfigUchar((UCHAR)BusNumber,
+ (UCHAR)SlotNumber,
+ (UCHAR)Address,
+ *(PUCHAR)Ptr);
+ Ptr = (char*)Ptr + 1;
+ Address++;
+ Len--;
+ }
+
+ return Length - Len;
+}
+
+
+static ULONG
+GetBusConfigType(VOID)
+{
+ ULONG Value;
+ KIRQL oldIrql;
+
+ DPRINT("GetBusConfigType() called\n");
+
+ KeAcquireSpinLock(&PciLock, &oldIrql);
+
+ DPRINT("Checking configuration type 1:");
+ WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
+ Value = READ_PORT_ULONG((PULONG)0xCF8);
+ WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
+ if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
+ {
+ WRITE_PORT_ULONG((PULONG)0xCF8, Value);
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ DPRINT(" Success!\n");
+ return 1;
+ }
+ WRITE_PORT_ULONG((PULONG)0xCF8, Value);
+ DPRINT(" Unsuccessful!\n");
+
+ DPRINT("Checking configuration type 2:");
+ WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
+ WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
+ WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
+ if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
+ READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
+ {
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ DPRINT(" Success!\n");
+ return 2;
+ }
+ KeReleaseSpinLock(&PciLock, oldIrql);
+ DPRINT(" Unsuccessful!\n");
+
+ DPRINT("No pci bus found!\n");
+ return 0;
+}
+
+
+static ULONG STDCALL
+HalpGetPciInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+
+static BOOLEAN STDCALL
+HalpTranslatePciAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ if (*AddressSpace == 0)
+ {
+ /* memory space */
+
+ }
+ else if (*AddressSpace == 1)
+ {
+ /* io space */
+
+ }
+ else
+ {
+ /* other */
+ return FALSE;
+ }
+
+ TranslatedAddress->QuadPart = BusAddress.QuadPart;
+
+ return TRUE;
+}
+
+/*
+ * Find the extent of a PCI decode..
+ */
+static ULONG STDCALL
+PciSize(ULONG Base, ULONG Mask)
+{
+ ULONG Size = Mask & Base; /* Find the significant bits */
+ Size = Size & ~(Size - 1); /* Get the lowest of them to find the decode size */
+ return Size;
+}
+
+static NTSTATUS STDCALL
+HalpAssignPciSlotResources(IN PBUS_HANDLER BusHandler,
+ IN ULONG BusNumber,
+ IN PUNICODE_STRING RegistryPath,
+ IN PUNICODE_STRING DriverClassName,
+ IN PDRIVER_OBJECT DriverObject,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SlotNumber,
+ IN OUT PCM_RESOURCE_LIST *AllocatedResources)
+{
+ ULONG DataSize;
+ PCI_COMMON_CONFIG PciConfig;
+ UINT Address;
+ UINT ResourceCount;
+ ULONG Size[PCI_TYPE0_ADDRESSES];
+ NTSTATUS Status = STATUS_SUCCESS;
+ UCHAR Offset;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+
+ /* FIXME: Should handle 64-bit addresses */
+
+ DataSize = HalpGetPciData(BusHandler,
+ BusNumber,
+ SlotNumber,
+ &PciConfig,
+ 0,
+ PCI_COMMON_HDR_LENGTH);
+ if (PCI_COMMON_HDR_LENGTH != DataSize)
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* Read the PCI configuration space for the device and store base address and
+ size information in temporary storage. Count the number of valid base addresses */
+ ResourceCount = 0;
+ for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
+ {
+ if (0xffffffff == PciConfig.u.type0.BaseAddresses[Address])
+ {
+ PciConfig.u.type0.BaseAddresses[Address] = 0;
+ }
+ if (0 != PciConfig.u.type0.BaseAddresses[Address])
+ {
+ ResourceCount++;
+ Offset = offsetof(PCI_COMMON_CONFIG, u.type0.BaseAddresses[Address]);
+ Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset, 0xffffffff);
+ if (! NT_SUCCESS(Status))
+ {
+ WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+ PciConfig.u.type0.BaseAddresses[Address]);
+ return Status;
+ }
+ Status = ReadPciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber,
+ Offset, Size + Address);
+ if (! NT_SUCCESS(Status))
+ {
+ WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+ PciConfig.u.type0.BaseAddresses[Address]);
+ return Status;
+ }
+ Status = WritePciConfigUlong((UCHAR)BusNumber, (UCHAR)SlotNumber, Offset,
+ PciConfig.u.type0.BaseAddresses[Address]);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ }
+
+ if (0 != PciConfig.u.type0.InterruptLine)
+ {
+ ResourceCount++;
+ }
+
+ /* Allocate output buffer and initialize */
+ *AllocatedResources = ExAllocatePoolWithTag(PagedPool,
+ sizeof(CM_RESOURCE_LIST) +
+ (ResourceCount - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR),
+ TAG_PCI);
+ if (NULL == *AllocatedResources)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ (*AllocatedResources)->Count = 1;
+ (*AllocatedResources)->List[0].InterfaceType = PCIBus;
+ (*AllocatedResources)->List[0].BusNumber = BusNumber;
+ (*AllocatedResources)->List[0].PartialResourceList.Version = 1;
+ (*AllocatedResources)->List[0].PartialResourceList.Revision = 1;
+ (*AllocatedResources)->List[0].PartialResourceList.Count = ResourceCount;
+ Descriptor = (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors;
+
+ /* Store configuration information */
+ for (Address = 0; Address < PCI_TYPE0_ADDRESSES; Address++)
+ {
+ if (0 != PciConfig.u.type0.BaseAddresses[Address])
+ {
+ if (PCI_BASE_ADDRESS_SPACE_MEMORY ==
+ (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
+ {
+ Descriptor->Type = CmResourceTypeMemory;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
+ Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE; /* FIXME Just a guess */
+ Descriptor->u.Memory.Start.QuadPart = (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_MEM_MASK);
+ Descriptor->u.Memory.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_MEM_MASK);
+ }
+ else if (PCI_BASE_ADDRESS_SPACE_IO ==
+ (PciConfig.u.type0.BaseAddresses[Address] & PCI_BASE_ADDRESS_SPACE))
+ {
+ Descriptor->Type = CmResourceTypePort;
+ Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; /* FIXME I have no idea... */
+ Descriptor->Flags = CM_RESOURCE_PORT_IO; /* FIXME Just a guess */
+ Descriptor->u.Port.Start.QuadPart = PciConfig.u.type0.BaseAddresses[Address] &= PCI_BASE_ADDRESS_IO_MASK;
+ Descriptor->u.Port.Length = PciSize(Size[Address], PCI_BASE_ADDRESS_IO_MASK & 0xffff);
+ }
+ else
+ {
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+ Descriptor++;
+ }
+ }
+
+ if (0 != PciConfig.u.type0.InterruptLine)
+ {
+ Descriptor->Type = CmResourceTypeInterrupt;
+ Descriptor->ShareDisposition = CmResourceShareShared; /* FIXME Just a guess */
+ Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; /* FIXME Just a guess */
+ Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
+ Descriptor->u.Interrupt.Vector = PciConfig.u.type0.InterruptLine;
+ Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
+
+ Descriptor++;
+ }
+
+ ASSERT(Descriptor == (*AllocatedResources)->List[0].PartialResourceList.PartialDescriptors + ResourceCount);
+
+ /* FIXME: Should store the resources in the registry resource map */
+
+ return Status;
+}
+
+
+VOID
+HalpInitPciBus(VOID)
+{
+ PBUS_HANDLER BusHandler;
+
+ DPRINT("HalpInitPciBus() called.\n");
+
+ KeInitializeSpinLock (&PciLock);
+
+ BusConfigType = GetBusConfigType();
+ if (BusConfigType == 0)
+ return;
+
+ DPRINT("Bus configuration %lu used\n", BusConfigType);
+
+ /* pci bus (bus 0) handler */
+ BusHandler = HalpAllocateBusHandler(PCIBus,
+ PCIConfiguration,
+ 0);
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetPciInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslatePciAddress;
+// BusHandler->AdjustResourceList =
+// (pGetSetBusData)HalpAdjustPciResourceList;
+ BusHandler->AssignSlotResources =
+ (pAssignSlotResources)HalpAssignPciSlotResources;
+ if (NULL != HalpHooks.InitPciBus)
+ {
+ HalpHooks.InitPciBus(0, BusHandler);
+ }
+
+
+ /* agp bus (bus 1) handler */
+ BusHandler = HalpAllocateBusHandler(PCIBus,
+ PCIConfiguration,
+ 1);
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetPciInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslatePciAddress;
+// BusHandler->AdjustResourceList =
+// (pGetSetBusData)HalpAdjustPciResourceList;
+ BusHandler->AssignSlotResources =
+ (pAssignSlotResources)HalpAssignPciSlotResources;
+ if (NULL != HalpHooks.InitPciBus)
+ {
+ HalpHooks.InitPciBus(1, BusHandler);
+ }
+
+
+ /* PCI bus (bus 2) handler */
+ BusHandler = HalpAllocateBusHandler(PCIBus,
+ PCIConfiguration,
+ 2);
+ BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
+ BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
+ BusHandler->GetInterruptVector =
+ (pGetInterruptVector)HalpGetPciInterruptVector;
+ BusHandler->TranslateBusAddress =
+ (pTranslateBusAddress)HalpTranslatePciAddress;
+// BusHandler->AdjustResourceList =
+// (pGetSetBusData)HalpAdjustPciResourceList;
+ BusHandler->AssignSlotResources =
+ (pAssignSlotResources)HalpAssignPciSlotResources;
+ if (NULL != HalpHooks.InitPciBus)
+ {
+ HalpHooks.InitPciBus(2, BusHandler);
+ }
+
+ DPRINT("HalpInitPciBus() finished.\n");
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N portio.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ portio.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,342 @@
+/* $Id: portio.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/portio.c
+ * PURPOSE: Port I/O functions
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 18/10/99
+ */
+
+#include <ddk/ntddk.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
+ * versions of the single-IO instructions (inb_p/inw_p/..).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+/*
+ * Thanks to James van Artsdalen for a better timing-fix than
+ * the two short jumps: using outb's to a nonexistent port seems
+ * to guarantee better timings even on fast machines.
+ *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe about using 0x80 (should be safe, though)
+ *
+ * Linus
+ */
+
+#if defined(__GNUC__)
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
+#else
+#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
+#endif
+
+#elif defined(_MSC_VER)
+
+#ifdef SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm jmp 1f __asm jmp 1f 1f:
+#else
+#define __SLOW_DOWN_IO __asm out 0x80, al
+#endif
+
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+#ifdef REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+VOID STDCALL
+READ_PORT_BUFFER_UCHAR (PUCHAR Port,
+ PUCHAR Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; insb\n\t"
+ : "=D" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov edi, Buffer
+ mov ecx, Count
+ cld
+ rep ins byte ptr[edi], dx
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_USHORT (PUSHORT Port,
+ PUSHORT Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; insw"
+ : "=D" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov edi, Buffer
+ mov ecx, Count
+ cld
+ rep ins word ptr[edi], dx
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+READ_PORT_BUFFER_ULONG (PULONG Port,
+ PULONG Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; insl"
+ : "=D" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov edi, Buffer
+ mov ecx, Count
+ cld
+ rep ins dword ptr[edi], dx
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+UCHAR STDCALL
+READ_PORT_UCHAR (PUCHAR Port)
+{
+ UCHAR Value;
+
+#if defined(__GNUC__)
+ __asm__("inb %w1, %0\n\t"
+ : "=a" (Value)
+ : "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ in al, dx
+ mov Value, al
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+ SLOW_DOWN_IO;
+ return(Value);
+}
+
+USHORT STDCALL
+READ_PORT_USHORT (PUSHORT Port)
+{
+ USHORT Value;
+
+#if defined(__GNUC__)
+ __asm__("inw %w1, %0\n\t"
+ : "=a" (Value)
+ : "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ in ax, dx
+ mov Value, ax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+ return(Value);
+}
+
+ULONG STDCALL
+READ_PORT_ULONG (PULONG Port)
+{
+ ULONG Value;
+
+#if defined(__GNUC__)
+ __asm__("inl %w1, %0\n\t"
+ : "=a" (Value)
+ : "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ in eax, dx
+ mov Value, eax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+ return(Value);
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_UCHAR (PUCHAR Port,
+ PUCHAR Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; outsb"
+ : "=S" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov esi, Buffer
+ mov ecx, Count
+ cld
+ rep outs
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_USHORT (PUSHORT Port,
+ PUSHORT Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; outsw"
+ : "=S" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov esi, Buffer
+ mov ecx, Count
+ cld
+ rep outsw
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_BUFFER_ULONG (PULONG Port,
+ PULONG Buffer,
+ ULONG Count)
+{
+#if defined(__GNUC__)
+ __asm__ __volatile__ ("cld ; rep ; outsl"
+ : "=S" (Buffer), "=c" (Count)
+ : "d" (Port),"0" (Buffer),"1" (Count));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov esi, Buffer
+ mov ecx, Count
+ cld
+ rep outsd
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+}
+
+VOID STDCALL
+WRITE_PORT_UCHAR (PUCHAR Port,
+ UCHAR Value)
+{
+#if defined(__GNUC__)
+ __asm__("outb %0, %w1\n\t"
+ :
+ : "a" (Value),
+ "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov al, Value
+ out dx,al
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+}
+
+VOID STDCALL
+WRITE_PORT_USHORT (PUSHORT Port,
+ USHORT Value)
+{
+#if defined(__GNUC__)
+ __asm__("outw %0, %w1\n\t"
+ :
+ : "a" (Value),
+ "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov ax, Value
+ out dx,ax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+}
+
+VOID STDCALL
+WRITE_PORT_ULONG (PULONG Port,
+ ULONG Value)
+{
+#if defined(__GNUC__)
+ __asm__("outl %0, %w1\n\t"
+ :
+ : "a" (Value),
+ "d" (Port));
+#elif defined(_MSC_VER)
+ __asm
+ {
+ mov edx, Port
+ mov eax, Value
+ out dx,eax
+ }
+#else
+#error Unknown compiler for inline assembler
+#endif
+ SLOW_DOWN_IO;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N processor.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ processor.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,50 @@
+/* $Id: processor.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/processor.c
+ * PURPOSE: Intel MultiProcessor specification support
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES: Parts adapted from linux SMP code
+ * UPDATE HISTORY:
+ * 22/05/1998 DW Created
+ * 12/04/2001 CSH Added MultiProcessor specification support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS *****************************************************************/
+
+VOID STDCALL
+HalInitializeProcessor(ULONG ProcessorNumber,
+ PVOID /*PLOADER_PARAMETER_BLOCK*/ LoaderBlock)
+{
+ DPRINT("HalInitializeProcessor(%x %x)\n", ProcessorNumber, LoaderBlock);
+}
+
+BOOLEAN STDCALL
+HalAllProcessorsStarted (VOID)
+{
+ DPRINT("HalAllProcessorsStarted()\n");
+
+ return TRUE;
+}
+
+BOOLEAN STDCALL
+HalStartNextProcessor(ULONG Unknown1,
+ ULONG ProcessorStack)
+{
+ DPRINT("HalStartNextProcessor(%x %x)\n", ProcessorNumber, ProcessorStack);
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N pwroff.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pwroff.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,121 @@
+/* $Id: pwroff.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * FILE : reactos/hal/x86/apm.c
+ * DESCRIPTION: Turn CPU off...
+ * PROJECT : ReactOS Operating System
+ * AUTHOR : D. Lindauer (July 11 1997)
+ * NOTE : This program is public domain
+ * REVISIONS :
+ * 1999-12-26
+ */
+
+#define APM_FUNCTION_AVAILABLE 0x5300
+#define APM_FUNCTION_CONNREAL 0x5301
+#define APM_FUNCTION_POWEROFF 0x5307
+#define APM_FUNCTION_ENABLECPU 0x530d
+#define APM_FUNCTION_ENABLEAPM 0x530e
+
+#define APM_DEVICE_BIOS 0
+#define APM_DEVICE_ALL 1
+
+#define APM_MODE_DISABLE 0
+#define APM_MODE_ENABLE 1
+
+
+
+#if defined(__GNUC__)
+
+nopm db 'No power management functionality',10,13,'$'
+errmsg db 'Power management error',10,13,'$'
+wrongver db 'Need APM version 1.1 or better',10,13,'$'
+;
+; Entry point
+;
+go:
+ mov dx,offset nopm
+ jc error
+ cmp ax,101h ; See if version 1.1 or greater
+ mov dx,offset wrongver
+ jc error
+
+ mov [ver],ax
+ mov ax,5301h ; Do a real mode connection
+ mov bx,0 ; device = BIOS
+ int 15h
+ jnc noconerr
+
+ cmp ah,2 ; Pass if already connected
+ mov dx,offset errmsg ; else error
+ jnz error
+noconerr:
+ mov ax,530eh ; Enable latest version of APM
+ mov bx,0 ; device = BIOS
+ mov cx,[ver] ; version
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov ax,530dh ; Now engage and enable CPU management
+ mov bx,1 ; device = all
+ mov cx,1 ; enable
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov ax,530fh
+ mov bx,1 ; device = ALL
+ mov cx,1 ; enable
+ int 15h
+ mov dx,offset errmsg
+ jc error
+
+ mov dx,offset errmsg
+error:
+ call print
+ mov ax,4c01h
+ int 21h
+ int 3
+ end start
+
+
+BOOLEAN
+ApmCall (
+ DWORD Function,
+ DWORD Device,
+ DWORD Mode
+ )
+{
+ /* AX <== Function */
+ /* BX <== Device */
+ /* CX <== Mode */
+ __asm__("int 21\n"); /* 0x15 */
+}
+
+#elif defined(_MSC_VER)
+#else
+#error Unknown compiler for inline assembler
+#endif
+
+
+BOOLEAN
+HalPowerOff (VOID)
+{
+ ApmCall (
+ APM_FUNCTION_AVAILABLE,
+ APM_DEVICE_BIOS,
+ 0
+ );
+ ApmCall (
+ APM_FUNCTION_ENABLEAPM,
+ );
+ /* Shutdown CPU */
+ ApmCall (
+ APM_FUNCTION_POWEROFF,
+ APM_DEVICE_ALL,
+ 3
+ );
+ return TRUE;
+}
+
+
+/* EOF */
reactos/hal/halx86/generic
diff -N reboot.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ reboot.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,72 @@
+/* $Id: reboot.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/reboot.c
+ * PURPOSE: Reboot functions.
+ * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * UPDATE HISTORY:
+ * Created 11/10/99
+ */
+
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+
+static VOID
+HalReboot (VOID)
+{
+ char data;
+ extern PVOID HalpZeroPageMapping;
+
+ /* enable warm reboot */
+ ((PUCHAR)HalpZeroPageMapping)[0x472] = 0x34;
+ ((PUCHAR)HalpZeroPageMapping)[0x473] = 0x12;
+
+ /* disable interrupts */
+ Ki386DisableInterrupts();
+
+
+ /* disable periodic interrupt (RTC) */
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0b);
+ data = READ_PORT_UCHAR((PUCHAR)0x71);
+ WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)(data & 0xbf));
+
+ /* */
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0x0a);
+ data = READ_PORT_UCHAR((PUCHAR)0x71);
+ WRITE_PORT_UCHAR((PUCHAR)0x71, (UCHAR)((data & 0xf0) | 0x06));
+
+ /* */
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0x15);
+
+ /* generate RESET signal via keyboard controller */
+ WRITE_PORT_UCHAR((PUCHAR)0x64, 0xfe);
+
+ /* stop the processor */
+#if 1
+ Ki386HaltProcessor();
+ for(;;);
+#endif
+}
+
+
+VOID STDCALL
+HalReturnToFirmware (
+ ULONG Action
+ )
+{
+ if (Action == FIRMWARE_HALT)
+ {
+ DbgPrint ("HalReturnToFirmware called!\n");
+ DbgBreakPoint ();
+ }
+ else if (Action == FIRMWARE_REBOOT)
+ {
+ HalReleaseDisplayOwnership();
+ HalReboot ();
+ }
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N resource.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ resource.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,32 @@
+/* $Id: resource.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/generic/resource.c
+ * PURPOSE: Miscellaneous resource functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+ /*
+ * FIXME: Report all resources used by hal.
+ * Calls IoReportHalResourceUsage()
+ */
+
+ /* Initialize PCI bus. */
+ HalpInitPciBus ();
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N spinlock.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ spinlock.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,101 @@
+/* $Id: spinlock.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/spinlock.c
+ * PURPOSE: Implements spinlocks
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 09/06/2000 Created
+ */
+
+/*
+ * NOTE: On a uniprocessor machine spinlocks are implemented by raising
+ * the irq level
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ddk/ntddk.h>
+
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID STDCALL
+KeAcquireSpinLock (
+ PKSPIN_LOCK SpinLock,
+ PKIRQL OldIrql
+ )
+/*
+ * FUNCTION: Acquires a spinlock
+ * ARGUMENTS:
+ * SpinLock = Spinlock to acquire
+ * OldIrql (OUT) = Caller supplied storage for the previous irql
+ */
+{
+ *OldIrql = KfAcquireSpinLock(SpinLock);
+}
+
+KIRQL FASTCALL
+KeAcquireSpinLockRaiseToSynch (
+ PKSPIN_LOCK SpinLock
+ )
+{
+ KIRQL OldIrql;
+
+ OldIrql = KfRaiseIrql(SYNCH_LEVEL);
+ KiAcquireSpinLock(SpinLock);
+
+ return OldIrql;
+}
+
+VOID STDCALL
+KeReleaseSpinLock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL NewIrql
+ )
+/*
+ * FUNCTION: Releases a spinlock
+ * ARGUMENTS:
+ * SpinLock = Spinlock to release
+ * NewIrql = Irql level before acquiring the spinlock
+ */
+{
+ KfReleaseSpinLock(SpinLock, NewIrql);
+}
+
+KIRQL FASTCALL
+KfAcquireSpinLock (
+ PKSPIN_LOCK SpinLock
+ )
+{
+ KIRQL OldIrql;
+
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
+ KiAcquireSpinLock(SpinLock);
+
+ return OldIrql;
+}
+
+VOID FASTCALL
+KfReleaseSpinLock (
+ PKSPIN_LOCK SpinLock,
+ KIRQL NewIrql
+ )
+/*
+ * FUNCTION: Releases a spinlock
+ * ARGUMENTS:
+ * SpinLock = Spinlock to release
+ * NewIrql = Irql level before acquiring the spinlock
+ */
+{
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL || KeGetCurrentIrql() == SYNCH_LEVEL);
+ KiReleaseSpinLock(SpinLock);
+ KfLowerIrql(NewIrql);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N sysbus.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sysbus.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,69 @@
+/* $Id: sysbus.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/sysbus.c
+ * PURPOSE: System bus handler functions
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * 09/04/2000 Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <bus.h>
+#include <halirq.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG STDCALL
+HalpGetSystemInterruptVector(PVOID BusHandler,
+ ULONG BusNumber,
+ ULONG BusInterruptLevel,
+ ULONG BusInterruptVector,
+ PKIRQL Irql,
+ PKAFFINITY Affinity)
+{
+ ULONG Vector = IRQ2VECTOR(BusInterruptVector);
+ *Irql = VECTOR2IRQL(Vector);
+ *Affinity = 0xFFFFFFFF;
+ return Vector;
+}
+
+
+BOOLEAN STDCALL
+HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ PHYSICAL_ADDRESS BusAddress,
+ PULONG AddressSpace,
+ PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ ULONG BaseAddress = 0;
+
+ if (*AddressSpace == 0)
+ {
+ /* memory space */
+
+ }
+ else if (*AddressSpace == 1)
+ {
+ /* io space */
+
+ }
+ else
+ {
+ /* other */
+ return FALSE;
+ }
+
+ TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
+
+ return TRUE;
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N sysinfo.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sysinfo.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,76 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/sysinfo.c
+ * PURPOSE: Getting system information
+ * PROGRAMMER: David Welch (welch@mcmail.com)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS STDCALL
+HalpQuerySystemInformation(IN HAL_QUERY_INFORMATION_CLASS InformationClass,
+ IN ULONG BufferSize,
+ IN OUT PVOID Buffer,
+ OUT PULONG ReturnedLength)
+{
+ ULONG DataLength;
+ NTSTATUS Status;
+
+ DPRINT1("HalpQuerySystemInformation() called\n");
+
+ *ReturnedLength = 0;
+
+ DataLength = 0;
+
+ switch(InformationClass)
+ {
+#if 0
+ case HalInstalledBusInformation:
+ Status = HalpQueryBusInformation(BufferSize,
+ Buffer,
+ ReturnedLength);
+ break;
+#endif
+
+ default:
+ DataLength = 0;
+ Status = STATUS_INVALID_LEVEL;
+ break;
+ }
+
+ if (DataLength != 0)
+ {
+ if (DataLength > BufferSize)
+ DataLength = BufferSize;
+
+// RtlCopyMemory();
+
+ *ReturnedLength = DataLength;
+ }
+
+ return(Status);
+}
+
+
+#if 0
+NTSTATUS
+HalpSetSystemInformation(VOID)
+{
+ UNIMPLEMENTED;
+}
+#endif
+
+/* EOF */
reactos/hal/halx86/generic
diff -N time.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ time.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,359 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/time.c
+ * PURPOSE: Getting time information
+ * UPDATE HISTORY:
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <string.h>
+#include <hal.h>
+#include <bus.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* MACROS and CONSTANTS ******************************************************/
+
+/* macro BCD_INT : convert bcd to int */
+#define BCD_INT(bcd) (((bcd & 0xf0) >> 4) * 10 + (bcd &0x0f))
+
+/* macro INT_BCD : convert int to bcd */
+#define INT_BCD(int) (((int / 10) << 4) + (int % 10))
+
+
+#define RTC_REGISTER_A 0x0A
+#define RTC_REG_A_UIP 0x80 /* Update In Progress bit */
+
+#define RTC_REGISTER_B 0x0B
+
+#define RTC_REGISTER_CENTURY 0x32
+
+/* GLOBALS ******************************************************************/
+
+static KSPIN_LOCK CmosLock = {0};
+
+/* FUNCTIONS *****************************************************************/
+
+
+static UCHAR
+HalpQueryCMOS(UCHAR Reg)
+{
+ UCHAR Val;
+ ULONG Flags;
+
+ Reg |= 0x80;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
+ Val = READ_PORT_UCHAR((PUCHAR)0x71);
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+
+ return(Val);
+}
+
+
+static VOID
+HalpSetCMOS(UCHAR Reg,
+ UCHAR Val)
+{
+ ULONG Flags;
+
+ Reg |= 0x80;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x70, Reg);
+ WRITE_PORT_UCHAR((PUCHAR)0x71, Val);
+ WRITE_PORT_UCHAR((PUCHAR)0x70, 0);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+}
+
+
+static UCHAR
+HalpQueryECMOS(USHORT Reg)
+{
+ UCHAR Val;
+ ULONG Flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
+ WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
+ Val = READ_PORT_UCHAR((PUCHAR)0x76);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+
+ return(Val);
+}
+
+
+static VOID
+HalpSetECMOS(USHORT Reg,
+ UCHAR Val)
+{
+ ULONG Flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x74, (UCHAR)(Reg & 0x00FF));
+ WRITE_PORT_UCHAR((PUCHAR)0x75, (UCHAR)(Reg>>8));
+ WRITE_PORT_UCHAR((PUCHAR)0x76, Val);
+
+ /* restore flags */
+ Ki386RestoreFlags(Flags);
+}
+
+
+VOID STDCALL
+HalQueryRealTimeClock(PTIME_FIELDS Time)
+{
+ KIRQL oldIrql;
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+ /* check 'Update In Progress' bit */
+ while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
+
+ Time->Second = BCD_INT(HalpQueryCMOS (0));
+ Time->Minute = BCD_INT(HalpQueryCMOS (2));
+ Time->Hour = BCD_INT(HalpQueryCMOS (4));
+ Time->Weekday = BCD_INT(HalpQueryCMOS (6));
+ Time->Day = BCD_INT(HalpQueryCMOS (7));
+ Time->Month = BCD_INT(HalpQueryCMOS (8));
+ Time->Year = BCD_INT(HalpQueryCMOS (9));
+
+ if (Time->Year > 80)
+ Time->Year += 1900;
+ else
+ Time->Year += 2000;
+
+#if 0
+ /* Century */
+ Time->Year += BCD_INT(HalpQueryCMOS (RTC_REGISTER_CENTURY)) * 100;
+#endif
+
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+#ifndef NDEBUG
+ DbgPrint ("HalQueryRealTimeClock() %d:%d:%d %d/%d/%d\n",
+ Time->Hour,
+ Time->Minute,
+ Time->Second,
+ Time->Day,
+ Time->Month,
+ Time->Year
+ );
+#endif
+
+ Time->Milliseconds = 0;
+}
+
+
+VOID STDCALL
+HalSetRealTimeClock(PTIME_FIELDS Time)
+{
+ KIRQL oldIrql;
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+ /* check 'Update In Progress' bit */
+ while (HalpQueryCMOS (RTC_REGISTER_A) & RTC_REG_A_UIP);
+
+ HalpSetCMOS (0, (UCHAR)INT_BCD(Time->Second));
+ HalpSetCMOS (2, (UCHAR)INT_BCD(Time->Minute));
+ HalpSetCMOS (4, (UCHAR)INT_BCD(Time->Hour));
+ HalpSetCMOS (6, (UCHAR)INT_BCD(Time->Weekday));
+ HalpSetCMOS (7, (UCHAR)INT_BCD(Time->Day));
+ HalpSetCMOS (8, (UCHAR)INT_BCD(Time->Month));
+ HalpSetCMOS (9, (UCHAR)INT_BCD(Time->Year % 100));
+
+#if 0
+ /* Century */
+ HalpSetCMOS (RTC_REGISTER_CENTURY, INT_BCD(Time->Year / 100));
+#endif
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+}
+
+
+BOOLEAN STDCALL
+HalGetEnvironmentVariable(PCH Name,
+ PCH Value,
+ USHORT ValueLength)
+{
+ KIRQL oldIrql;
+
+
+ if (_stricmp(Name, "LastKnownGood") != 0)
+ {
+ return FALSE;
+ }
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ if (HalpQueryCMOS(RTC_REGISTER_B) & 0x01)
+ {
+ strncpy(Value, "FALSE", ValueLength);
+ }
+ else
+ {
+ strncpy(Value, "TRUE", ValueLength);
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+ return TRUE;
+}
+
+
+BOOLEAN STDCALL
+HalSetEnvironmentVariable(PCH Name,
+ PCH Value)
+{
+ UCHAR Val;
+ KIRQL oldIrql;
+ BOOLEAN result = TRUE;
+
+ if (_stricmp(Name, "LastKnownGood") != 0)
+ return FALSE;
+
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+
+ Val = HalpQueryCMOS(RTC_REGISTER_B);
+
+ if (_stricmp(Value, "TRUE") == 0)
+ HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val | 0x01));
+ else if (_stricmp(Value, "FALSE") == 0)
+ HalpSetCMOS(RTC_REGISTER_B, (UCHAR)(Val & ~0x01));
+ else
+ result = FALSE;
+
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+
+ return result;
+}
+
+
+ULONG STDCALL
+HalpGetCmosData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PUCHAR Ptr = Buffer;
+ ULONG Address = SlotNumber;
+ ULONG Len = Length;
+ KIRQL oldIrql;
+
+ DPRINT("HalpGetCmosData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if (Length == 0)
+ return 0;
+
+ if (BusNumber == 0)
+ {
+ /* CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x100))
+ {
+ *Ptr = HalpQueryCMOS((UCHAR)Address);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+ else if (BusNumber == 1)
+ {
+ /* Extended CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x1000))
+ {
+ *Ptr = HalpQueryECMOS((USHORT)Address);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+
+ return(Length - Len);
+}
+
+
+ULONG STDCALL
+HalpSetCmosData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ PUCHAR Ptr = (PUCHAR)Buffer;
+ ULONG Address = SlotNumber;
+ ULONG Len = Length;
+ KIRQL oldIrql;
+
+ DPRINT("HalpSetCmosData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if (Length == 0)
+ return 0;
+
+ if (BusNumber == 0)
+ {
+ /* CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x100))
+ {
+ HalpSetCMOS((UCHAR)Address, *Ptr);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+ else if (BusNumber == 1)
+ {
+ /* Extended CMOS */
+ KeAcquireSpinLock(&CmosLock, &oldIrql);
+ while ((Len > 0) && (Address < 0x1000))
+ {
+ HalpSetECMOS((USHORT)Address, *Ptr);
+ Ptr = Ptr + 1;
+ Address++;
+ Len--;
+ }
+ KeReleaseSpinLock(&CmosLock, oldIrql);
+ }
+
+ return(Length - Len);
+}
+
+/* EOF */
reactos/hal/halx86/generic
diff -N timer.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ timer.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,366 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2000 David Welch <welch@cwcom.net>
+ * Copyright (C) 1999 Gareth Owen <gaz@athene.co.uk>, Ramon von Handel
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This software 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 software 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 software; see the file COPYING. If not, write
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ * MA 02139, USA.
+ *
+ */
+/* $Id: timer.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/udelay.c
+ * PURPOSE: Busy waiting
+ * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
+ * UPDATE HISTORY:
+ * 06/11/99 Created
+ */
+
+/* INCLUDES ***************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ps.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/
+
+static unsigned int delay_count = 1;
+
+#define TMR_CTRL 0x43 /* I/O for control */
+#define TMR_CNT0 0x40 /* I/O for counter 0 */
+#define TMR_CNT1 0x41 /* I/O for counter 1 */
+#define TMR_CNT2 0x42 /* I/O for counter 2 */
+
+#define TMR_SC0 0 /* Select channel 0 */
+#define TMR_SC1 0x40 /* Select channel 1 */
+#define TMR_SC2 0x80 /* Select channel 2 */
+
+#define TMR_LOW 0x10 /* RW low byte only */
+#define TMR_HIGH 0x20 /* RW high byte only */
+#define TMR_BOTH 0x30 /* RW both bytes */
+
+#define TMR_MD0 0 /* Mode 0 */
+#define TMR_MD1 0x2 /* Mode 1 */
+#define TMR_MD2 0x4 /* Mode 2 */
+#define TMR_MD3 0x6 /* Mode 3 */
+#define TMR_MD4 0x8 /* Mode 4 */
+#define TMR_MD5 0xA /* Mode 5 */
+
+#define TMR_BCD 1 /* BCD mode */
+
+#define TMR_LATCH 0 /* Latch command */
+
+#define TMR_READ 0xF0 /* Read command */
+#define TMR_CNT 0x20 /* CNT bit (Active low, subtract it) */
+#define TMR_STAT 0x10 /* Status bit (Active low, subtract it) */
+#define TMR_CH2 0x8 /* Channel 2 bit */
+#define TMR_CH1 0x4 /* Channel 1 bit */
+#define TMR_CH0 0x2 /* Channel 0 bit */
+
+#define MILLISEC 10 /* Number of millisec between interrupts */
+#define HZ (1000 / MILLISEC) /* Number of interrupts per second */
+#define CLOCK_TICK_RATE 1193182 /* Clock frequency of the timer chip */
+#define LATCH (CLOCK_TICK_RATE / HZ) /* Count to program into the timer chip */
+#define PRECISION 8 /* Number of bits to calibrate for delay loop */
+
+static BOOLEAN UdelayCalibrated = FALSE;
+
+/* FUNCTIONS **************************************************************/
+
+/*
+ * NOTE: This function MUST NOT be optimized by the compiler!
+ * If it is, it obviously will not delay AT ALL, and the system
+ * will appear completely frozen at boot since
+ * HalpCalibrateStallExecution will never return.
+ * There are three options to stop optimization:
+ * 1. Use a volatile automatic variable. Making it delay quite a bit
+ * due to memory accesses, and keeping the code portable. However,
+ * as this involves memory access it depends on both the CPU cache,
+ * e.g. if the stack used is already in a cache line or not, and
+ * whether or not we're MP. If MP, another CPU could (probably would)
+ * also access RAM at the same time - making the delay imprecise.
+ * 2. Use compiler-specific #pragma's to disable optimization.
+ * 3. Use inline assembly, making it equally unportable as #2.
+ * For supported compilers we use inline assembler. For the others,
+ * portable plain C.
+ */
+VOID STDCALL
+__KeStallExecutionProcessor(ULONG Loops)
+{
+ if (!Loops)
+ {
+ return;
+ }
+#if defined(__GNUC__)
+ __asm__ __volatile__ (
+ "mov %0, %%eax\n"
+ "ROSL1: dec %%eax\n"
+ "jnz ROSL1" : : "d" (Loops));
+
+#elif defined(_MSC_VER)
+ __asm mov eax, Loops
+ROSL1:
+ __asm dec eax
+ __asm jnz ROSL1
+#else
+ volatile unsigned int target = Loops;
+ unsigned int i;
+ for (i=0; i<target;i++);
+#endif
+}
+
+VOID STDCALL KeStallExecutionProcessor(ULONG Microseconds)
+{
+ PKPCR Pcr = KeGetCurrentKPCR();
+
+ if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+ {
+ LARGE_INTEGER EndCount, CurrentCount;
+ Ki386RdTSC(EndCount);
+ EndCount.QuadPart += Microseconds * (ULONGLONG)Pcr->PrcbData.MHz;
+ do
+ {
+ Ki386RdTSC(CurrentCount);
+ }
+ while (CurrentCount.QuadPart < EndCount.QuadPart);
+ }
+ else
+ {
+ __KeStallExecutionProcessor((Pcr->StallScaleFactor*Microseconds)/1000);
+ }
+}
+
+static ULONG Read8254Timer(VOID)
+{
+ ULONG Count;
+ ULONG flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_LATCH);
+ Count = READ_PORT_UCHAR((PUCHAR) TMR_CNT0);
+ Count |= READ_PORT_UCHAR((PUCHAR) TMR_CNT0) << 8;
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+
+ return Count;
+}
+
+
+static VOID WaitFor8254Wraparound(VOID)
+{
+ ULONG CurCount, PrevCount = ~0;
+ LONG Delta;
+
+ CurCount = Read8254Timer();
+
+ do
+ {
+ PrevCount = CurCount;
+ CurCount = Read8254Timer();
+ Delta = CurCount - PrevCount;
+
+ /*
+ * This limit for delta seems arbitrary, but it isn't, it's
+ * slightly above the level of error a buggy Mercury/Neptune
+ * chipset timer can cause.
+ */
+
+ }
+ while (Delta < 300);
+}
+
+VOID HalpCalibrateStallExecution(VOID)
+{
+ ULONG i;
+ ULONG calib_bit;
+ ULONG CurCount;
+ PKPCR Pcr;
+ LARGE_INTEGER StartCount, EndCount;
+
+ if (UdelayCalibrated)
+ {
+ return;
+ }
+
+ UdelayCalibrated = TRUE;
+ Pcr = KeGetCurrentKPCR();
+
+ /* Initialise timer interrupt with MILLISEC ms interval */
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CTRL, TMR_SC0 | TMR_BOTH | TMR_MD2); /* binary, mode 2, LSB/MSB, ch 0 */
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH & 0xff); /* LSB */
+ WRITE_PORT_UCHAR((PUCHAR) TMR_CNT0, LATCH >> 8); /* MSB */
+
+ if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+ {
+
+ WaitFor8254Wraparound();
+ Ki386RdTSC(StartCount);
+
+ WaitFor8254Wraparound();
+ Ki386RdTSC(EndCount);
+
+ Pcr->PrcbData.MHz = (ULONG)(EndCount.QuadPart - StartCount.QuadPart) / 10000;
+ DPRINT("%dMHz\n", Pcr->PrcbData.MHz);
+ return;
+
+ }
+
+ DbgPrint("Calibrating delay loop... [");
+
+ /* Stage 1: Coarse calibration */
+
+ WaitFor8254Wraparound();
+
+ delay_count = 1;
+
+ do
+ {
+ delay_count <<= 1; /* Next delay count to try */
+
+ WaitFor8254Wraparound();
+
+ __KeStallExecutionProcessor(delay_count); /* Do the delay */
+
+ CurCount = Read8254Timer();
+ }
+ while (CurCount > LATCH / 2);
+
+ delay_count >>= 1; /* Get bottom value for delay */
+
+ /* Stage 2: Fine calibration */
+ DbgPrint("delay_count: %d", delay_count);
+
+ calib_bit = delay_count; /* Which bit are we going to test */
+
+ for (i = 0; i < PRECISION; i++)
+ {
+ calib_bit >>= 1; /* Next bit to calibrate */
+ if (!calib_bit)
+ {
+ break; /* If we have done all bits, stop */
+ }
+
+ delay_count |= calib_bit; /* Set the bit in delay_count */
+
+ WaitFor8254Wraparound();
+
+ __KeStallExecutionProcessor(delay_count); /* Do the delay */
+
+ CurCount = Read8254Timer();
+ if (CurCount <= LATCH / 2) /* If a tick has passed, turn the */
+ { /* calibrated bit back off */
+ delay_count &= ~calib_bit;
+ }
+ }
+
+ /* We're finished: Do the finishing touches */
+
+ delay_count /= (MILLISEC / 2); /* Calculate delay_count for 1ms */
+
+ DbgPrint("]\n");
+ DbgPrint("delay_count: %d\n", delay_count);
+ DbgPrint("CPU speed: %d\n", delay_count / 250);
+#if 0
+ DbgPrint("About to start delay loop test\n");
+ DbgPrint("Waiting for five minutes...");
+ for (i = 0; i < (5*60*1000*20); i++)
+ {
+ KeStallExecutionProcessor(50);
+ }
+ DbgPrint("finished\n");
+ for(;;);
+#endif
+}
+
+
+VOID STDCALL
+HalCalibratePerformanceCounter(ULONG Count)
+{
+ ULONG flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ __KeStallExecutionProcessor(Count);
+
+ /* restore flags */
+ Ki386RestoreFlags(flags);
+}
+
+
+LARGE_INTEGER STDCALL
+KeQueryPerformanceCounter(PLARGE_INTEGER PerformanceFreq)
+/*
+ * FUNCTION: Queries the finest grained running count available in the system
+ * ARGUMENTS:
+ * PerformanceFreq (OUT) = The routine stores the number of
+ * performance counter ticks per second here
+ * RETURNS: The number of performance counter ticks since boot
+ */
+{
+ PKPCR Pcr;
+ LARGE_INTEGER Value;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ Pcr = KeGetCurrentKPCR();
+
+ if (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC)
+ {
+ Ki386RestoreFlags(Flags);
+ if (NULL != PerformanceFreq)
+ {
+ PerformanceFreq->QuadPart = Pcr->PrcbData.MHz * (ULONGLONG)1000000;
+ }
+ Ki386RdTSC(Value);
+ }
+ else
+ {
+ LARGE_INTEGER TicksOld;
+ LARGE_INTEGER TicksNew;
+ ULONG CountsLeft;
+
+ Ki386RestoreFlags(Flags);
+
+ if (NULL != PerformanceFreq)
+ {
+ PerformanceFreq->QuadPart = CLOCK_TICK_RATE;
+ }
+
+ do
+ {
+ KeQueryTickCount(&TicksOld);
+ CountsLeft = Read8254Timer();
+ Value.QuadPart = TicksOld.QuadPart * LATCH + (LATCH - CountsLeft);
+ KeQueryTickCount(&TicksNew);
+ }
+ while (TicksOld.QuadPart != TicksNew.QuadPart);
+ }
+ return Value;
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map
reactos/hal/halx86/mp
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 13 Dec 2004 16:18:23 -0000 1.4.2.1
@@ -0,0 +1,90 @@
+# $Id: Makefile,v 1.4.2.1 2004/12/13 16:18:23 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+TARGET_NAME = halmp
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DMP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DMP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+ifneq ($(MP), 1)
+TARGET_INSTALL = no
+else
+TARGET_BOOTSTRAP = yes
+endif
+
+GENERIC_OBJECTS = \
+ adapter.o \
+ beep.o \
+ bus.o \
+ display.o \
+ dma.o \
+ drive.o \
+ enum.o \
+ fmutex.o \
+ halinit.o \
+ isa.o \
+ kdbg.o \
+ mca.o \
+ misc.o \
+ pci.o \
+ portio.o \
+ reboot.o \
+ spinlock.o \
+ sysbus.o \
+ sysinfo.o \
+ time.o \
+ timer.o
+
+MP_OBJECTS = \
+ apic.o \
+ halinit_mp.o \
+ ipi_mp.o \
+ mpsirql.o \
+ mpsboot.o \
+ mps.o \
+ processor_mp.o \
+ resource_mp.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(MP_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF
reactos/hal/halx86/mp
diff -N apic.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ apic.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,853 @@
+/*
+ * ReactOS kernel
+ * Copyright (C) 2004 ReactOS Team
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/* $Id: apic.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/apic.c
+ * PURPOSE:
+ * PROGRAMMER:
+ */
+
+#include <ddk/ntddk.h>
+#include <internal/i386/ps.h>
+
+#include <hal.h>
+#include <halirq.h>
+#include <mps.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+BOOLEAN VerifyLocalAPIC(VOID);
+VOID APICCalibrateTimer(ULONG CPU);
+
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
+
+extern ULONG APICMode; /* APIC mode at startup */
+extern PULONG BIOSBase; /* Virtual address of BIOS data segment */
+extern PULONG CommonBase; /* Virtual address of common area */
+extern ULONG BootCPU; /* Bootstrap processor */
+extern ULONG OnlineCPUs; /* Bitmask of online CPUs */
+
+extern CHAR *APstart, *APend;
+extern VOID (*APflush)(VOID);
+
+#define CMOS_READ(address) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
+ READ_PORT_UCHAR((PUCHAR)0x71)); \
+})
+
+#define CMOS_WRITE(address, value) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
+ WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
+})
+
+#define BIOS_AREA 0x0
+#define COMMON_AREA 0x2000
+
+
+extern CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
+
+PULONG APICBase = (PULONG)APIC_DEFAULT_BASE; /* Virtual address of local APIC */
+
+/* For debugging */
+ULONG lastregr[MAX_CPU];
+ULONG lastvalr[MAX_CPU];
+ULONG lastregw[MAX_CPU];
+ULONG lastvalw[MAX_CPU];
+
+ULONG APICGetMaxLVT(VOID)
+{
+ ULONG tmp, ver, maxlvt;
+
+ tmp = APICRead(APIC_VER);
+ ver = GET_APIC_VERSION(tmp);
+ /* 82489DXs do not report # of LVT entries. */
+ maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(tmp) : 2;
+
+ return maxlvt;
+}
+
+VOID APICClear(VOID)
+{
+ ULONG tmp, maxlvt;
+
+ maxlvt = APICGetMaxLVT();
+
+ /*
+ * Careful: we have to set masks only first to deassert
+ * any level-triggered sources.
+ */
+
+ if (maxlvt >= 3)
+ {
+ tmp = ERROR_VECTOR;
+ APICWrite(APIC_LVT3, tmp | APIC_LVT3_MASKED);
+ }
+
+ tmp = APICRead(APIC_LVTT);
+ APICWrite(APIC_LVTT, tmp | APIC_LVT_MASKED);
+
+ tmp = APICRead(APIC_LINT0);
+ APICWrite(APIC_LINT0, tmp | APIC_LVT_MASKED);
+
+ tmp = APICRead(APIC_LINT1);
+ APICWrite(APIC_LINT1, tmp | APIC_LVT_MASKED);
+
+ if (maxlvt >= 4)
+ {
+ tmp = APICRead(APIC_LVTPC);
+ APICWrite(APIC_LVTPC, tmp | APIC_LVT_MASKED);
+ }
+#if 0
+ if (maxlvt >= 5)
+ {
+ tmp = APICRead(APIC_LVTTHMR);
+ APICWrite(APIC_LVTTHMR, tmp | APIC_LVT_MASKED);
+ }
+#endif
+ /*
+ * Clean APIC state for other OSs:
+ */
+ APICWrite(APIC_LVTT, APIC_LVT_MASKED);
+ APICWrite(APIC_LINT0, APIC_LVT_MASKED);
+ APICWrite(APIC_LINT1, APIC_LVT_MASKED);
+
+ if (maxlvt >= 3)
+ {
+ APICWrite(APIC_LVT3, APIC_LVT3_MASKED);
+ }
+
+ if (maxlvt >= 4)
+ {
+ APICWrite(APIC_LVTPC, APIC_LVT_MASKED);
+ }
+#if 0
+ if (maxlvt >= 5)
+ {
+ APICWrite(APIC_LVTTHMR, APIC_LVT_MASKED);
+ }
+#endif
+}
+
+/* Enable symetric I/O mode ie. connect the BSP's local APIC to INT and NMI lines */
+VOID EnableSMPMode(VOID)
+{
+ /*
+ * Do not trust the local APIC being empty at bootup.
+ */
+ APICClear();
+
+ WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
+ WRITE_PORT_UCHAR((PUCHAR)0x23, 0x01);
+}
+
+/* Disable symetric I/O mode ie. go to PIC mode */
+inline VOID DisableSMPMode(VOID)
+{
+ /*
+ * Put the board back into PIC mode (has an effect
+ * only on certain older boards). Note that APIC
+ * interrupts, including IPIs, won't work beyond
+ * this point! The only exception are INIT IPIs.
+ */
+ WRITE_PORT_UCHAR((PUCHAR)0x22, 0x70);
+ WRITE_PORT_UCHAR((PUCHAR)0x23, 0x00);
+}
+
+VOID DumpESR(VOID)
+{
+ ULONG tmp;
+
+ if (APICGetMaxLVT() > 3)
+ {
+ APICWrite(APIC_ESR, 0);
+ }
+ tmp = APICRead(APIC_ESR);
+ DbgPrint("ESR %08x\n", tmp);
+}
+
+
+VOID APICDisable(VOID)
+{
+ ULONG tmp;
+
+ APICClear();
+
+ /*
+ * Disable APIC (implies clearing of registers for 82489DX!).
+ */
+ tmp = APICRead(APIC_SIVR);
+ tmp &= ~APIC_SIVR_ENABLE;
+ APICWrite(APIC_SIVR, tmp);
+}
+
+VOID HaliInitBSP(VOID)
+{
+ PUSHORT ps;
+ static BOOLEAN BSPInitialized = FALSE;
+
+ /* Only initialize the BSP once */
+ if (BSPInitialized)
+ {
+ KEBUGCHECK(0);
+ return;
+ }
+
+ BSPInitialized = TRUE;
+
+ DPRINT("APIC is mapped at 0x%X\n", APICBase);
+
+ if (VerifyLocalAPIC())
+ {
+ DPRINT("APIC found\n");
+ }
+ else
+ {
+ DPRINT("No APIC found\n");
+ KEBUGCHECK(0);
+ }
+
+ if (APICMode == amPIC)
+ {
+ EnableSMPMode();
+ }
+
+ APICSetup();
+
+ /* BIOS data segment */
+ BIOSBase = (PULONG)BIOS_AREA;
+
+ /* Area for communicating with the APs */
+ CommonBase = (PULONG)COMMON_AREA;
+
+ /* Copy bootstrap code to common area */
+ memcpy((PVOID)((ULONG)CommonBase + PAGE_SIZE),
+ &APstart,
+ (ULONG)&APend - (ULONG)&APstart + 1);
+
+ /* Set shutdown code */
+ CMOS_WRITE(0xF, 0xA);
+
+ /* Set warm reset vector */
+ ps = (PUSHORT)((ULONG)BIOSBase + 0x467);
+ *ps = (COMMON_AREA + PAGE_SIZE) & 0xF;
+
+ ps = (PUSHORT)((ULONG)BIOSBase + 0x469);
+ *ps = (COMMON_AREA + PAGE_SIZE) >> 4;
+
+ /* Calibrate APIC timer */
+ APICCalibrateTimer(BootCPU);
+}
+
+volatile inline ULONG _APICRead(ULONG Offset)
+{
+ PULONG p;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+ return *p;
+}
+
+#if 0
+inline VOID APICWrite(ULONG Offset,
+ ULONG Value)
+{
+ PULONG p;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+
+ *p = Value;
+}
+#else
+inline VOID APICWrite(ULONG Offset,
+ ULONG Value)
+{
+ PULONG p;
+ ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+
+ lastregw[CPU] = Offset;
+ lastvalw[CPU] = Value;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+
+ *p = Value;
+}
+#endif
+
+
+#if 0
+volatile inline ULONG APICRead(ULONG Offset)
+{
+ PULONG p;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+ return *p;
+}
+#else
+volatile inline ULONG APICRead(ULONG Offset)
+{
+ PULONG p;
+ ULONG CPU = (_APICRead(APIC_ID) & APIC_ID_MASK) >> 24;
+
+ lastregr[CPU] = Offset;
+ lastvalr[CPU] = 0;
+
+ p = (PULONG)((ULONG)APICBase + Offset);
+
+ lastvalr[CPU] = *p;
+ return lastvalr[CPU];
+}
+#endif
+
+inline VOID APICSendEOI(VOID)
+{
+ // Send the EOI
+ APICWrite(APIC_EOI, 0);
+}
+
+static VOID APICDumpBit(ULONG base)
+{
+ ULONG v, i, j;
+
+ DbgPrint("0123456789abcdef0123456789abcdef\n");
+ for (i = 0; i < 8; i++)
+ {
+ v = APICRead(base + i*0x10);
+ for (j = 0; j < 32; j++)
+ {
+ if (v & (1<<j))
+ DbgPrint("1");
+ else
+ DbgPrint("0");
+ }
+ DbgPrint("\n");
+ }
+}
+
+
+VOID APICDump(VOID)
+/*
+ * Dump the contents of the local APIC registers
+ */
+{
+ ULONG v, ver, maxlvt;
+ ULONG r1, r2, w1, w2;
+ ULONG CPU = ThisCPU();;
+
+
+
+ r1 = lastregr[CPU];
+ r2 = lastvalr[CPU];
+ w1 = lastregw[CPU];
+ w2 = lastvalw[CPU];
+
+ DbgPrint("\nPrinting local APIC contents on CPU(%d):\n", ThisCPU());
+ v = APICRead(APIC_ID);
+ DbgPrint("... ID : %08x (%01x) ", v, GET_APIC_ID(v));
+ v = APICRead(APIC_VER);
+ DbgPrint("... VERSION: %08x\n", v);
+ ver = GET_APIC_VERSION(v);
+ maxlvt = APICGetMaxLVT();
+
+ v = APICRead(APIC_TPR);
+ DbgPrint("... TPR : %08x (%02x)", v, v & ~0);
+
+ if (APIC_INTEGRATED(ver))
+ {
+ /* !82489DX */
+ v = APICRead(APIC_APR);
+ DbgPrint("... APR : %08x (%02x)\n", v, v & ~0);
+ v = APICRead(APIC_PPR);
+ DbgPrint("... PPR : %08x\n", v);
+ }
+
+ v = APICRead(APIC_EOI);
+ DbgPrint("... EOI : %08x ! ", v);
+ v = APICRead(APIC_LDR);
+ DbgPrint("... LDR : %08x\n", v);
+ v = APICRead(APIC_DFR);
+ DbgPrint("... DFR : %08x ! ", v);
+ v = APICRead(APIC_SIVR);
+ DbgPrint("... SIVR : %08x\n", v);
+
+ if (0)
+ {
+ DbgPrint("... ISR field:\n");
+ APICDumpBit(APIC_ISR);
+ DbgPrint("... TMR field:\n");
+ APICDumpBit(APIC_TMR);
+ DbgPrint("... IRR field:\n");
+ APICDumpBit(APIC_IRR);
+ }
+
+ if (APIC_INTEGRATED(ver))
+ {
+ /* !82489DX */
+ if (maxlvt > 3)
+ {
+ /* Due to the Pentium erratum 3AP. */
+ APICWrite(APIC_ESR, 0);
+ }
+ v = APICRead(APIC_ESR);
+ DbgPrint("... ESR : %08x\n", v);
+ }
+
+ v = APICRead(APIC_ICR0);
+ DbgPrint("... ICR0 : %08x ! ", v);
+ v = APICRead(APIC_ICR1);
+ DbgPrint("... ICR1 : %08x ! ", v);
+
+ v = APICRead(APIC_LVTT);
+ DbgPrint("... LVTT : %08x\n", v);
+
+ if (maxlvt > 3)
+ {
+ /* PC is LVT#4. */
+ v = APICRead(APIC_LVTPC);
+ DbgPrint("... LVTPC : %08x ! ", v);
+ }
+ v = APICRead(APIC_LINT0);
+ DbgPrint("... LINT0 : %08x ! ", v);
+ v = APICRead(APIC_LINT1);
+ DbgPrint("... LINT1 : %08x\n", v);
+
+ if (maxlvt > 2)
+ {
+ v = APICRead(APIC_LVT3);
+ DbgPrint("... LVT3 : %08x\n", v);
+ }
+
+ v = APICRead(APIC_ICRT);
+ DbgPrint("... ICRT : %08x ! ", v);
+ v = APICRead(APIC_CCRT);
+ DbgPrint("... CCCT : %08x ! ", v);
+ v = APICRead(APIC_TDCR);
+ DbgPrint("... TDCR : %08x\n", v);
+ DbgPrint("\n");
+ DbgPrint("Last register read (offset): 0x%08X\n", r1);
+ DbgPrint("Last register read (value): 0x%08X\n", r2);
+ DbgPrint("Last register written (offset): 0x%08X\n", w1);
+ DbgPrint("Last register written (value): 0x%08X\n", w2);
+ DbgPrint("\n");
+}
+
+BOOLEAN VerifyLocalAPIC(VOID)
+{
+ UINT reg0, reg1;
+ CHECKPOINT1;
+ /* The version register is read-only in a real APIC */
+ reg0 = APICRead(APIC_VER);
+ DPRINT1("Getting VERSION: %x\n", reg0);
+ APICWrite(APIC_VER, reg0 ^ APIC_VER_MASK);
+ reg1 = APICRead(APIC_VER);
+ DPRINT1("Getting VERSION: %x\n", reg1);
+
+ /*
+ * The two version reads above should print the same
+ * numbers. If the second one is different, then we
+ * poke at a non-APIC.
+ */
+
+ if (reg1 != reg0)
+ {
+ return FALSE;
+ }
+
+ /*
+ * Check if the version looks reasonably.
+ */
+ reg1 = GET_APIC_VERSION(reg0);
+ if (reg1 == 0x00 || reg1 == 0xff)
+ {
+ return FALSE;
+ }
+ reg1 = APICGetMaxLVT();
+ if (reg1 < 0x02 || reg1 == 0xff)
+ {
+ return FALSE;
+ }
+
+ /*
+ * The ID register is read/write in a real APIC.
+ */
+ reg0 = APICRead(APIC_ID);
+ DPRINT1("Getting ID: %x\n", reg0);
+ APICWrite(APIC_ID, reg0 ^ APIC_ID_MASK);
+ reg1 = APICRead(APIC_ID);
+ DPRINT1("Getting ID: %x\n", reg1);
+ APICWrite(APIC_ID, reg0);
+ if (reg1 != (reg0 ^ APIC_ID_MASK))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+VOID APICSendIPI(ULONG Target, ULONG Mode)
+{
+ ULONG tmp, i, flags;
+
+ /* save flags and disable interrupts */
+ Ki386SaveFlags(flags);
+ Ki386DisableInterrupts();
+
+ /* Wait up to 100ms for the APIC to become ready */
+ for (i = 0; i < 10000; i++)
+ {
+ tmp = APICRead(APIC_ICR0);
+ /* Check Delivery Status */
+ if ((tmp & APIC_ICR0_DS) == 0)
+ break;
+ KeStallExecutionProcessor(10);
+ }
+
+ if (i == 10000)
+ {
+ DPRINT1("CPU(%d) Previous IPI was not delivered after 100ms.\n", ThisCPU());
+ }
+
+ /* Setup the APIC to deliver the IPI */
+ DPRINT("%08x %x\n", SET_APIC_DEST_FIELD(Target), Target);
+ APICWrite(APIC_ICR1, SET_APIC_DEST_FIELD(Target));
+
+ if (Target == APIC_TARGET_SELF)
+ {
+ Mode |= APIC_ICR0_DESTS_SELF;
+ }
+ else if (Target == APIC_TARGET_ALL)
+ {
+ Mode |= APIC_ICR0_DESTS_ALL;
+ }
+ else if (Target == APIC_TARGET_ALL_BUT_SELF)
+ {
+ Mode |= APIC_ICR0_DESTS_ALL_BUT_SELF;
+ }
+ else
+ {
+ Mode |= APIC_ICR0_DESTS_FIELD;
+ }
+
+ /* Now, fire off the IPI */
+ APICWrite(APIC_ICR0, Mode);
+
+ /* Wait up to 100ms for the APIC to become ready */
+ for (i = 0; i < 10000; i++)
+ {
+ tmp = APICRead(APIC_ICR0);
+ /* Check Delivery Status */
+ if ((tmp & APIC_ICR0_DS) == 0)
+ break;
+ KeStallExecutionProcessor(10);
+ }
+
+ if (i == 10000)
+ {
+ DPRINT1("CPU(%d) Current IPI was not delivered after 100ms.\n", ThisCPU());
+ }
+ Ki386RestoreFlags(flags);
+}
+
+VOID APICSetup(VOID)
+{
+ ULONG CPU, tmp;
+
+ CPU = ThisCPU();
+
+// APICDump();
+
+ DPRINT1("CPU%d:\n", CPU);
+ DPRINT1(" Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
+ DPRINT1(" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
+ DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
+
+ /*
+ * Intel recommends to set DFR, LDR and TPR before enabling
+ * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
+ * document number 292116). So here it goes...
+ */
+
+ /*
+ * Put the APIC into flat delivery mode.
+ * Must be "all ones" explicitly for 82489DX.
+ */
+ APICWrite(APIC_DFR, 0xFFFFFFFF);
+
+ /*
+ * Set up the logical destination ID.
+ */
+ tmp = APICRead(APIC_LDR);
+ tmp &= ~APIC_LDR_MASK;
+ /*
+ * FIXME:
+ * This works only up to 8 CPU's
+ */
+ tmp |= (1 << (KeGetCurrentProcessorNumber() + 24));
+ APICWrite(APIC_LDR, tmp);
+
+
+ DPRINT1("CPU%d:\n", CPU);
+ DPRINT1(" Physical APIC id: %d\n", GET_APIC_ID(APICRead(APIC_ID)));
+ DPRINT1(" Logical APIC id: %d\n", GET_APIC_LOGICAL_ID(APICRead(APIC_LDR)));
+ DPRINT1("%08x %08x %08x\n", APICRead(APIC_ID), APICRead(APIC_LDR), APICRead(APIC_DFR));
+ DPRINT1("%d\n", CPUMap[CPU].APICId);
+
+ /* Accept only higher interrupts */
+ APICWrite(APIC_TPR, 0xef);
+
+ /* Enable local APIC */
+ tmp = APICRead(APIC_SIVR);
+ tmp &= ~0xff;
+ tmp |= APIC_SIVR_ENABLE;
+
+#if 0
+ tmp &= ~APIC_SIVR_FOCUS;
+#else
+ tmp |= APIC_SIVR_FOCUS;
+#endif
+
+ /* Set spurious interrupt vector */
+ tmp |= SPURIOUS_VECTOR;
+ APICWrite(APIC_SIVR, tmp);
+
+ /*
+ * Set up LVT0, LVT1:
+ *
+ * set up through-local-APIC on the BP's LINT0. This is not
+ * strictly necessery in pure symmetric-IO mode, but sometimes
+ * we delegate interrupts to the 8259A.
+ */
+ tmp = APICRead(APIC_LINT0) & APIC_LVT_MASKED;
+ if (CPU == BootCPU && (APICMode == amPIC || !tmp))
+ {
+ tmp = APIC_DM_EXTINT;
+ DPRINT1("enabled ExtINT on CPU#%d\n", CPU);
+ }
+ else
+ {
+ tmp = APIC_DM_EXTINT | APIC_LVT_MASKED;
+ DPRINT1("masked ExtINT on CPU#%d\n", CPU);
+ }
+ APICWrite(APIC_LINT0, tmp);
+
+
+ /*
+ * Only the BSP should see the LINT1 NMI signal, obviously.
+ */
+ if (CPU == BootCPU)
+ {
+ tmp = APIC_DM_NMI;
+ }
+ else
+ {
+ tmp = APIC_DM_NMI | APIC_LVT_MASKED;
+ }
+ if (!APIC_INTEGRATED(CPUMap[CPU].APICVersion))
+ {
+ /* 82489DX */
+ tmp |= APIC_LVT_LEVEL_TRIGGER;
+ }
+ APICWrite(APIC_LINT1, tmp);
+
+ if (APIC_INTEGRATED(CPUMap[CPU].APICVersion))
+ {
+ /* !82489DX */
+ if (APICGetMaxLVT() > 3)
+ {
+ /* Due to the Pentium erratum 3AP */
+ APICWrite(APIC_ESR, 0);
+ }
+
+ tmp = APICRead(APIC_ESR);
+ DPRINT("ESR value before enabling vector: 0x%X\n", tmp);
+
+ /* Enable sending errors */
+ tmp = ERROR_VECTOR;
+ APICWrite(APIC_LVT3, tmp);
+
+ /*
+ * Spec says clear errors after enabling vector
+ */
+ if (APICGetMaxLVT() > 3)
+ {
+ APICWrite(APIC_ESR, 0);
+ }
+ tmp = APICRead(APIC_ESR);
+ DPRINT("ESR value after enabling vector: 0x%X\n", tmp);
+ }
+}
+
+VOID APICSyncArbIDs(VOID)
+{
+ ULONG i, tmp;
+
+ /* Wait up to 100ms for the APIC to become ready */
+ for (i = 0; i < 10000; i++)
+ {
+ tmp = APICRead(APIC_ICR0);
+ /* Check Delivery Status */
+ if ((tmp & APIC_ICR0_DS) == 0)
+ break;
+ KeStallExecutionProcessor(10);
+ }
+
+ if (i == 10000)
+ {
+ DPRINT("CPU(%d) APIC busy for 100ms.\n", ThisCPU());
+ }
+
+ DPRINT("Synchronizing Arb IDs.\n");
+ APICWrite(APIC_ICR0, APIC_ICR0_DESTS_ALL | APIC_ICR0_LEVEL | APIC_DM_INIT);
+}
+
+VOID MpsErrorHandler(VOID)
+{
+ ULONG tmp1, tmp2;
+
+ APICDump();
+
+ tmp1 = APICRead(APIC_ESR);
+ APICWrite(APIC_ESR, 0);
+ tmp2 = APICRead(APIC_ESR);
+ DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
+
+ /*
+ * Acknowledge the interrupt
+ */
+ APICSendEOI();
+
+ /* Here is what the APIC error bits mean:
+ * 0: Send CS error
+ * 1: Receive CS error
+ * 2: Send accept error
+ * 3: Receive accept error
+ * 4: Reserved
+ * 5: Send illegal vector
+ * 6: Received illegal vector
+ * 7: Illegal register address
+ */
+ DPRINT1("APIC error on CPU(%d) ESR(%x)(%x)\n", ThisCPU(), tmp1, tmp2);
+ for (;;);
+}
+
+VOID MpsSpuriousHandler(VOID)
+{
+ ULONG tmp;
+
+ DPRINT1("Spurious interrupt on CPU(%d)\n", ThisCPU());
+
+ tmp = APICRead(APIC_ISR + ((SPURIOUS_VECTOR & ~0x1f) >> 1));
+ if (tmp & (1 << (SPURIOUS_VECTOR & 0x1f)))
+ {
+ APICSendEOI();
+ return;
+ }
+#if 0
+ /* No need to send EOI here */
+ APICDump();
+#endif
+}
+
+VOID MpsIpiHandler(VOID)
+{
+ KIRQL oldIrql;
+
+ HalBeginSystemInterrupt(IPI_VECTOR,
+ VECTOR2IRQL(IPI_VECTOR),
+ &oldIrql);
+ Ki386EnableInterrupts();
+#if 0
+ DbgPrint("(%s:%d) MpsIpiHandler on CPU%d, current irql is %d\n",
+ __FILE__,__LINE__, KeGetCurrentProcessorNumber(), KeGetCurrentIrql());
+#endif
+
+ KiIpiServiceRoutine(NULL, NULL);
+
+#if 0
+ DbgPrint("(%s:%d) MpsIpiHandler on CPU%d done\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber());
+#endif
+
+ Ki386DisableInterrupts();
+ HalEndSystemInterrupt(oldIrql, 0);
+}
+
+VOID
+MpsIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
+ PKTRAP_FRAME TrapFrame)
+{
+ TrapFrame->Gs = (USHORT)IrqTrapFrame->Gs;
+ TrapFrame->Fs = (USHORT)IrqTrapFrame->Fs;
+ TrapFrame->Es = (USHORT)IrqTrapFrame->Es;
+ TrapFrame->Ds = (USHORT)IrqTrapFrame->Ds;
+ TrapFrame->Eax = IrqTrapFrame->Eax;
+ TrapFrame->Ecx = IrqTrapFrame->Ecx;
+ TrapFrame->Edx = IrqTrapFrame->Edx;
+ TrapFrame->Ebx = IrqTrapFrame->Ebx;
+ TrapFrame->Esp = IrqTrapFrame->Esp;
+ TrapFrame->Ebp = IrqTrapFrame->Ebp;
+ TrapFrame->Esi = IrqTrapFrame->Esi;
+ TrapFrame->Edi = IrqTrapFrame->Edi;
+ TrapFrame->Eip = IrqTrapFrame->Eip;
+ TrapFrame->Cs = IrqTrapFrame->Cs;
+ TrapFrame->Eflags = IrqTrapFrame->Eflags;
+}
+
+VOID
+MpsTimerHandler(ULONG Vector, PKIRQ_TRAPFRAME Trapframe)
+{
+ KIRQL oldIrql;
+ KTRAP_FRAME KernelTrapFrame;
+#if 0
+ ULONG CPU;
+ static ULONG Count[MAX_CPU] = {0,};
+#endif
+ HalBeginSystemInterrupt(LOCAL_TIMER_VECTOR,
+ VECTOR2IRQL(LOCAL_TIMER_VECTOR),
+ &oldIrql);
+ Ki386EnableInterrupts();
+
+#if 0
+ CPU = ThisCPU();
+ if ((Count[CPU] % 100) == 0)
+ {
+ DbgPrint("(%s:%d) MpsTimerHandler on CPU%d, irql = %d, epi = %x, KPCR = %x\n", __FILE__, __LINE__, CPU, oldIrql,Trapframe->Eip, KeGetCurrentKPCR());
+ }
+ Count[CPU]++;
+#endif
+
+ MpsIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
+ if (KeGetCurrentProcessorNumber() == 0)
+ {
+ KeUpdateSystemTime(&KernelTrapFrame, oldIrql);
+ }
+ else
+ {
+ KeUpdateRunTime(&KernelTrapFrame, oldIrql);
+ }
+
+ Ki386DisableInterrupts();
+ HalEndSystemInterrupt (oldIrql, 0);
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N halinit_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit_mp.c 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,29 @@
+/* $Id: halinit_mp.c,v 1.1.2.1 2004/12/13 16:18:23 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <mps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+ HalpInitMPS();
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N halmp.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halmp.rc 13 Dec 2004 16:18:23 -0000 1.1.2.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "X86 Multiprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halx86mp\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halx86mp.dll\0"
+#include <reactos/version.rc>
reactos/hal/halx86/mp
diff -N ipi_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ipi_mp.c 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,29 @@
+/* $Id: ipi_mp.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mp/ipi_mp.c
+ * PURPOSE: IPI functions for MP
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID STDCALL
+HalRequestIpi(ULONG ProcessorNo)
+{
+ DPRINT("HalRequestIpi(ProcessorNo %d)\n", ProcessorNo);
+ APICSendIPI(1 << ProcessorNo,
+ IPI_VECTOR|APIC_ICR0_LEVEL_DEASSERT|APIC_ICR0_DESTM);
+}
+
+/* EOF */
reactos/hal/halx86/mp
diff -N mps.S
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mps.S 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,109 @@
+/* $Id: mps.S,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/mps.S
+ * PURPOSE: Intel MultiProcessor specification support
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * Created 12/04/2001
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <internal/i386/segment.h>
+
+/* FUNCTIONS *****************************************************************/
+
+#define BEFORE \
+ cld; \
+ pusha; \
+ pushl %ds; \
+ pushl %es; \
+ pushl %fs; \
+ pushl %gs; \
+ movl $(KERNEL_DS), %eax; \
+ movl %eax, %ds; \
+ movl %eax, %es; \
+ movl %eax, %gs; \
+ movl $(PCR_SELECTOR), %eax; \
+ movl %eax, %fs;
+
+#define AFTER \
+ popl %gs; \
+ popl %fs; \
+ popl %es; \
+ popl %ds; \
+ popa;
+
+.global _MpsIpiInterrupt
+_MpsIpiInterrupt:
+ /* Save registers */
+ BEFORE
+
+ /* Call the C handler */
+ call _MpsIpiHandler
+
+ /* Return to the caller */
+ AFTER
+ iret
+
+
+.globl _MpsErrorInterrupt
+_MpsErrorInterrupt:
+ /* Save registers */
+ BEFORE
+
+ /* Call the C handler */
+ call _MpsErrorHandler
+
+ /* Return to the caller */
+ AFTER
+ iret
+
+
+.globl _MpsSpuriousInterrupt
+_MpsSpuriousInterrupt:
+ /* Save registers */
+ BEFORE
+
+ /* Call the C handler */
+ call _MpsSpuriousHandler
+
+ /* Return to the caller */
+ AFTER
+ iret
+
+.global _MpsTimerInterrupt
+_MpsTimerInterrupt:
+ cld
+ pusha
+ movl $0xef,%ebx
+ pushl %ds
+ pushl %es
+ pushl %fs
+ pushl %gs
+ movl $0xceafbeef,%eax
+ pushl %eax
+ movl $(KERNEL_DS),%eax
+ movl %eax,%ds
+ movl %eax,%es
+ movl %eax,%gs
+ movl $(PCR_SELECTOR),%eax
+ movl %eax,%fs
+ pushl %esp
+ pushl %ebx
+ call _MpsTimerHandler
+ popl %eax
+ popl %eax
+ popl %eax
+ popl %gs
+ popl %fs
+ popl %es
+ popl %ds
+ popa
+ iret
+
+
+
+/* EOF */
reactos/hal/halx86/mp
diff -N mpsboot.asm
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mpsboot.asm 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,106 @@
+;
+; COPYRIGHT: See COPYING in the top level directory
+; PROJECT: ReactOS kernel
+; FILE: ntoskrnl/hal/x86/mpsboot.c
+; PURPOSE: Bootstrap code for application processors
+; PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+; UPDATE HISTORY:
+; Created 12/04/2001
+;
+
+;
+; Memory map at this stage is:
+; 0x2000 Location of our stack
+; 0x3000 Startup code for the APs (this code)
+;
+
+;
+; Base address of common area for BSP and APs
+;
+LOAD_BASE equ 00200000h
+
+;
+; Magic value to be put in EAX when multiboot.S is called as part of the
+; application processor initialization process
+;
+AP_MAGIC equ 12481020h
+
+;
+; Segment selectors
+;
+%define KERNEL_CS (0x8)
+%define KERNEL_DS (0x10)
+
+section .text
+
+global _APstart
+global _APend
+
+; 16 bit code
+BITS 16
+
+_APstart:
+ cli ; Just in case
+
+ xor ax, ax
+ mov ds, ax
+ mov ss, ax
+
+ mov eax, 3000h + APgdt - _APstart
+ lgdt [eax]
+
+ mov eax, cr0
+ or eax, 00010001h ; Turn on protected mode and write protection
+ mov cr0, eax
+
+ db 0eah
+ dw 3000h + flush - _APstart, KERNEL_CS
+
+; 32 bit code
+BITS 32
+
+flush:
+ mov ax, KERNEL_DS
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ ; Setup a stack for the AP
+ mov eax, 2000h
+ mov eax, [eax]
+ mov esp, eax
+
+ ; Jump to start of the kernel with AP magic in eax
+ mov eax, AP_MAGIC
+ jmp dword KERNEL_CS:(LOAD_BASE + 0x1000)
+
+ ; Never get here
+
+
+; Temporary GDT descriptor for the APs
+
+APgdt:
+; Limit
+ dw (3*8)-1
+; Base
+ dd 3000h + gdt - _APstart
+
+gdt:
+ dw 0x0 ; Null descriptor
+ dw 0x0
+ dw 0x0
+ dw 0x0
+
+ dw 0xffff ; Kernel code descriptor
+ dw 0x0000
+ dw 0x9a00
+ dw 0x00cf
+
+ dw 0xffff ; Kernel data descriptor
+ dw 0x0000
+ dw 0x9200
+ dw 0x00cf
+
+_APend:
reactos/hal/halx86/mp
diff -N mpsirql.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mpsirql.c 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,400 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/mpsirql.c
+ * PURPOSE: Implements IRQLs for multiprocessor systems
+ * PROGRAMMERS: David Welch (welch@cwcom.net)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * UPDATE HISTORY:
+ * 12/04/2001 CSH Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ke.h>
+#include <internal/ps.h>
+#include <ntos/minmax.h>
+#include <halirq.h>
+#include <hal.h>
+#include <mps.h>
+#include <apic.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ******************************************************************/;
+
+
+/* FUNCTIONS ****************************************************************/
+
+KIRQL STDCALL KeGetCurrentIrql (VOID)
+/*
+ * PURPOSE: Returns the current irq level
+ * RETURNS: The current irq level
+ */
+{
+ KIRQL irql;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ irql = Ki386ReadFsByte(offsetof(KPCR, Irql));
+ if (irql > HIGH_LEVEL)
+ {
+ DPRINT1 ("CurrentIrql %x\n", irql);
+ KEBUGCHECK (0);
+ }
+ if (Flags & X86_EFLAGS_IF)
+ {
+ Ki386EnableInterrupts();
+ }
+ return irql;
+}
+
+
+VOID KeSetCurrentIrql (KIRQL NewIrql)
+/*
+ * PURPOSE: Sets the current irq level without taking any action
+ */
+{
+ ULONG Flags;
+ if (NewIrql > HIGH_LEVEL)
+ {
+ DPRINT1 ("NewIrql %x\n", NewIrql);
+ KEBUGCHECK (0);
+ }
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ Ki386WriteFsByte(offsetof(KPCR, Irql), NewIrql);
+ if (Flags & X86_EFLAGS_IF)
+ {
+ Ki386EnableInterrupts();
+ }
+}
+
+VOID
+HalpLowerIrql(KIRQL NewIrql, BOOL FromHalEndSystemInterrupt)
+{
+ ULONG Flags;
+ if (NewIrql >= DISPATCH_LEVEL)
+ {
+ KeSetCurrentIrql (NewIrql);
+ APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
+ return;
+ }
+ Ki386SaveFlags(Flags);
+ if (KeGetCurrentIrql() > APC_LEVEL)
+ {
+ KeSetCurrentIrql (DISPATCH_LEVEL);
+ APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI);
+ if (FromHalEndSystemInterrupt || Ki386ReadFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST])))
+ {
+ Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 0);
+ Ki386EnableInterrupts();
+ KiDispatchInterrupt();
+ if (!(Flags & X86_EFLAGS_IF))
+ {
+ Ki386DisableInterrupts();
+ }
+ }
+ KeSetCurrentIrql (APC_LEVEL);
+ }
+ if (NewIrql == APC_LEVEL)
+ {
+ return;
+ }
+ if (KeGetCurrentThread () != NULL &&
+ KeGetCurrentThread ()->ApcState.KernelApcPending)
+ {
+ Ki386EnableInterrupts();
+ KiDeliverApc(KernelMode, NULL, NULL);
+ if (!(Flags & X86_EFLAGS_IF))
+ {
+ Ki386DisableInterrupts();
+ }
+ }
+ KeSetCurrentIrql (PASSIVE_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+VOID FASTCALL
+KfLowerIrql (KIRQL NewIrql)
+{
+ KIRQL oldIrql = KeGetCurrentIrql();
+ if (NewIrql > oldIrql)
+ {
+ DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
+ KEBUGCHECK (0);
+ }
+ HalpLowerIrql (NewIrql, FALSE);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeLowerIrql
+ *
+ * DESCRIPTION
+ * Restores the irq level on the current processor
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to lower to
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ */
+
+VOID STDCALL
+KeLowerIrql (KIRQL NewIrql)
+{
+ KfLowerIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KfRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ *
+ * RETURN VALUE
+ * previous irq level
+ *
+ * NOTES
+ * Uses fastcall convention
+ */
+
+KIRQL FASTCALL
+KfRaiseIrql (KIRQL NewIrql)
+{
+ KIRQL OldIrql;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ OldIrql = KeGetCurrentIrql ();
+
+ if (NewIrql < OldIrql)
+ {
+ DPRINT1 ("CurrentIrql %x NewIrql %x\n", KeGetCurrentIrql (), NewIrql);
+ KEBUGCHECK (0);
+ }
+
+
+ if (NewIrql > DISPATCH_LEVEL)
+ {
+ APICWrite (APIC_TPR, IRQL2TPR(NewIrql) & APIC_TPR_PRI);
+ }
+ KeSetCurrentIrql (NewIrql);
+ if (Flags & X86_EFLAGS_IF)
+ {
+ Ki386EnableInterrupts();
+ }
+
+ return OldIrql;
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrql
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql)
+ *
+ * ARGUMENTS
+ * NewIrql = Irql to raise to
+ * OldIrql (OUT) = Caller supplied storage for the previous irql
+ *
+ * RETURN VALUE
+ * None
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+VOID STDCALL
+KeRaiseIrql (KIRQL NewIrql,
+ PKIRQL OldIrql)
+{
+ *OldIrql = KfRaiseIrql (NewIrql);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToDpcLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to DISPATCH level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToDpcLevel (VOID)
+{
+ return KfRaiseIrql (DISPATCH_LEVEL);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * KeRaiseIrqlToSynchLevel
+ *
+ * DESCRIPTION
+ * Raises the hardware priority (irql) to CLOCK2 level
+ *
+ * ARGUMENTS
+ * None
+ *
+ * RETURN VALUE
+ * Previous irq level
+ *
+ * NOTES
+ * Calls KfRaiseIrql
+ */
+
+KIRQL STDCALL
+KeRaiseIrqlToSynchLevel (VOID)
+{
+ return KfRaiseIrql (CLOCK2_LEVEL);
+}
+
+
+BOOLEAN STDCALL
+HalBeginSystemInterrupt (ULONG Vector,
+ KIRQL Irql,
+ PKIRQL OldIrql)
+{
+ ULONG Flags;
+ DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql);
+
+ if (KeGetCurrentIrql () >= Irql)
+ {
+ DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
+ KEBUGCHECK(0);
+ }
+
+ Ki386SaveFlags(Flags);
+ if (Flags & X86_EFLAGS_IF)
+ {
+ DPRINT1("HalBeginSystemInterrupt was called with interrupt's enabled\n");
+ KEBUGCHECK(0);
+ }
+ APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
+ *OldIrql = KeGetCurrentIrql ();
+ KeSetCurrentIrql (Irql);
+ return(TRUE);
+}
+
+
+VOID STDCALL
+HalEndSystemInterrupt (KIRQL Irql,
+ ULONG Unknown2)
+/*
+ * FUNCTION: Finish a system interrupt and restore the specified irq level.
+ */
+{
+ ULONG Flags;
+ Ki386SaveFlags(Flags);
+
+ if (Flags & X86_EFLAGS_IF)
+ {
+ DPRINT1("HalEndSystemInterrupt was called with interrupt's enabled\n");
+ KEBUGCHECK(0);
+ }
+ APICSendEOI();
+ HalpLowerIrql (Irql, TRUE);
+}
+
+BOOLEAN STDCALL
+HalDisableSystemInterrupt (ULONG Vector,
+ KIRQL Irql)
+{
+ ULONG irq;
+
+ DPRINT ("Vector (0x%X)\n", Vector);
+
+ if (Vector < FIRST_DEVICE_VECTOR ||
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
+ DPRINT1("Not a device interrupt, vector=%x\n", Vector);
+ return FALSE;
+ }
+
+ irq = VECTOR2IRQ (Vector);
+ IOAPICMaskIrq (irq);
+
+ return TRUE;
+}
+
+
+BOOLEAN STDCALL
+HalEnableSystemInterrupt (ULONG Vector,
+ KIRQL Irql,
+ KINTERRUPT_MODE InterruptMode)
+{
+ ULONG irq;
+
+ if (Vector < FIRST_DEVICE_VECTOR ||
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
+ DPRINT("Not a device interrupt\n");
+ return FALSE;
+ }
+
+ irq = VECTOR2IRQ (Vector);
+ IOAPICUnmaskIrq (irq);
+
+ return TRUE;
+}
+
+VOID FASTCALL
+HalRequestSoftwareInterrupt(IN KIRQL Request)
+{
+ switch (Request)
+ {
+ case APC_LEVEL:
+ Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_APC_REQUEST]), 1);
+ break;
+
+ case DISPATCH_LEVEL:
+ Ki386WriteFsByte(offsetof(KPCR, HalReserved[HAL_DPC_REQUEST]), 1);
+ break;
+
+ default:
+ KEBUGCHECK(0);
+ }
+}
reactos/hal/halx86/mp
diff -N processor_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ processor_mp.c 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,1807 @@
+/* $Id: processor_mp.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mp/processor_mp.c
+ * PURPOSE: Intel MultiProcessor specification support
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES: Parts adapted from linux SMP code
+ * UPDATE HISTORY:
+ * 22/05/1998 DW Created
+ * 12/04/2001 CSH Added MultiProcessor specification support
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <halirq.h>
+#include <mps.h>
+#include <apic.h>
+
+#include <internal/ntoskrnl.h>
+#include <internal/i386/segment.h>
+#include <internal/ke.h>
+#include <internal/ps.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/*
+ Address of area to be used for communication between Application
+ Processors (APs) and the BootStrap Processor (BSP)
+ */
+#define COMMON_AREA 0x2000
+
+#define BIOS_AREA 0x0
+
+typedef struct __attribute__((packed)) _COMMON_AREA_INFO
+{
+ ULONG Stack; /* Location of AP stack */
+ ULONG Debug[16]; /* For debugging */
+} COMMON_AREA_INFO, *PCOMMON_AREA_INFO;
+
+CPU_INFO CPUMap[MAX_CPU]; /* Map of all CPUs in the system */
+ULONG CPUCount; /* Total number of CPUs */
+ULONG OnlineCPUs; /* Bitmask of online CPUs */
+
+UCHAR BUSMap[MAX_BUS]; /* Map of all buses in the system */
+UCHAR PCIBUSMap[MAX_BUS]; /* Map of all PCI buses in the system */
+
+IOAPIC_INFO IOAPICMap[MAX_IOAPIC]; /* Map of all I/O APICs in the system */
+ULONG IOAPICCount; /* Number of I/O APICs in the system */
+
+MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
+ULONG IRQVectorMap[MAX_IRQ_SOURCE]; /* IRQ to vector map */
+ULONG IrqPinMap[MAX_IRQ_SOURCE]; /* IRQ to Pin map */
+ULONG IrqApicMap[MAX_IRQ_SOURCE];
+ULONG IRQCount; /* Number of IRQs */
+
+ULONG APICMode; /* APIC mode at startup */
+ULONG BootCPU; /* Bootstrap processor */
+PULONG BIOSBase; /* Virtual address of BIOS data segment */
+PULONG CommonBase; /* Virtual address of common area */
+
+extern CHAR *APstart, *APend;
+extern VOID (*APflush)(VOID);
+
+extern VOID MpsTimerInterrupt(VOID);
+extern VOID MpsErrorInterrupt(VOID);
+extern VOID MpsSpuriousInterrupt(VOID);
+extern VOID MpsIpiInterrupt(VOID);
+
+#define CMOS_READ(address) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address)); \
+ READ_PORT_UCHAR((PUCHAR)0x71)); \
+})
+
+#define CMOS_WRITE(address, value) ({ \
+ WRITE_PORT_UCHAR((PUCHAR)0x70, address); \
+ WRITE_PORT_UCHAR((PUCHAR)0x71, value); \
+})
+
+
+/* FUNCTIONS *****************************************************************/
+
+/* Functions for handling 8259A PICs */
+
+VOID Disable8259AIrq(ULONG irq)
+{
+ ULONG tmp;
+
+ if (irq >= 8)
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
+ tmp |= (1 << (irq - 8));
+ WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
+ }
+ else
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0x21);
+ tmp |= (1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
+ }
+}
+
+
+VOID Enable8259AIrq(ULONG irq)
+{
+ ULONG tmp;
+
+ if (irq >= 8)
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
+ tmp &= ~(1 << (irq - 8));
+ WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
+ }
+ else
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0x21);
+ tmp &= ~(1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
+ }
+}
+
+
+/* Functions for handling I/O APICs */
+
+volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset)
+{
+ PULONG Base;
+
+ Base = (PULONG)IOAPICMap[Apic].ApicAddress;
+ *Base = Offset;
+ return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
+}
+
+VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
+{
+ PULONG Base;
+
+ Base = (PULONG)IOAPICMap[Apic].ApicAddress;
+ *Base = Offset;
+ *((PULONG)((ULONG)Base + IOAPIC_IOWIN)) = Value;
+}
+
+
+VOID IOAPICClearPin(ULONG Apic, ULONG Pin)
+{
+ IOAPIC_ROUTE_ENTRY Entry;
+
+ DPRINT("IOAPICClearPin(Apic %d, Pin %d\n", Apic, Pin);
+ /*
+ * Disable it in the IO-APIC irq-routing table
+ */
+ memset(&Entry, 0, sizeof(Entry));
+ Entry.mask = 1;
+
+ IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
+ IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
+}
+
+static VOID IOAPICClear(ULONG Apic)
+{
+ ULONG Pin;
+
+ for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
+ {
+ IOAPICClearPin(Apic, Pin);
+ }
+}
+
+static VOID IOAPICClearAll(VOID)
+{
+ ULONG Apic;
+
+ for (Apic = 0; Apic < IOAPICCount; Apic++)
+ {
+ IOAPICClear(Apic);
+ }
+}
+
+/* This is performance critical and should probably be done in assembler */
+VOID IOAPICMaskIrq(ULONG Irq)
+{
+ IOAPIC_ROUTE_ENTRY Entry;
+ ULONG Apic = IrqApicMap[Irq];
+
+
+ *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
+ Entry.mask = 1;
+ IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
+}
+
+
+/* This is performance critical and should probably be done in assembler */
+VOID IOAPICUnmaskIrq(ULONG Irq)
+{
+ IOAPIC_ROUTE_ENTRY Entry;
+ ULONG Apic = IrqApicMap[Irq];
+
+ *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq]);
+ Entry.mask = 0;
+ IOAPICWrite(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq], *((PULONG)&Entry));
+}
+
+static VOID
+IOAPICSetupIds(VOID)
+{
+ ULONG tmp, apic, i;
+ UCHAR old_id;
+
+ /*
+ * Set the IOAPIC ID to the value stored in the MPC table.
+ */
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+
+ /* Read the register 0 value */
+ tmp = IOAPICRead(apic, IOAPIC_ID);
+
+ old_id = IOAPICMap[apic].ApicId;
+
+ if (IOAPICMap[apic].ApicId >= 0xf)
+ {
+ DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
+ apic, IOAPICMap[apic].ApicId);
+ DPRINT1("... fixing up to %d. (tell your hw vendor)\n",
+ GET_IOAPIC_ID(tmp));
+ IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
+ }
+
+ /*
+ * We need to adjust the IRQ routing table
+ * if the ID changed.
+ */
+ if (old_id != IOAPICMap[apic].ApicId)
+ {
+ for (i = 0; i < IRQCount; i++)
+ {
+ if (IRQMap[i].DstApicId == old_id)
+ {
+ IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;
+ }
+ }
+ }
+
+ /*
+ * Read the right value from the MPC table and
+ * write it into the ID register.
+ */
+ DPRINT("Changing IO-APIC physical APIC ID to %d\n",
+ IOAPICMap[apic].ApicId);
+
+ tmp &= ~IOAPIC_ID_MASK;
+ tmp |= SET_IOAPIC_ID(IOAPICMap[apic].ApicId);
+
+ IOAPICWrite(apic, IOAPIC_ID, tmp);
+
+ /*
+ * Sanity check
+ */
+ tmp = IOAPICRead(apic, 0);
+ if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId)
+ {
+ DPRINT1("Could not set I/O APIC ID!\n");
+ KEBUGCHECK(0);
+ }
+ }
+}
+
+
+/*
+ * EISA Edge/Level control register, ELCR
+ */
+static ULONG EISA_ELCR(ULONG irq)
+{
+ if (irq < 16)
+ {
+ PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
+ return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
+ }
+ DPRINT("Broken MPtable reports ISA irq %d\n", irq);
+ return 0;
+}
+
+/* EISA interrupts are always polarity zero and can be edge or level
+ * trigger depending on the ELCR value. If an interrupt is listed as
+ * EISA conforming in the MP table, that means its trigger type must
+ * be read in from the ELCR */
+
+#define default_EISA_trigger(idx) (EISA_ELCR(IRQMap[idx].SrcBusIrq))
+#define default_EISA_polarity(idx) (0)
+
+/* ISA interrupts are always polarity zero edge triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_ISA_trigger(idx) (0)
+#define default_ISA_polarity(idx) (0)
+
+/* PCI interrupts are always polarity one level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_PCI_trigger(idx) (1)
+#define default_PCI_polarity(idx) (1)
+
+/* MCA interrupts are always polarity zero level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_MCA_trigger(idx) (1)
+#define default_MCA_polarity(idx) (0)
+
+static ULONG IRQPolarity(ULONG idx)
+{
+ ULONG bus = IRQMap[idx].SrcBusId;
+ ULONG polarity;
+
+ /*
+ * Determine IRQ line polarity (high active or low active):
+ */
+ switch (IRQMap[idx].IrqFlag & 3)
+ {
+ case 0: /* conforms, ie. bus-type dependent polarity */
+ {
+ switch (BUSMap[bus])
+ {
+ case MP_BUS_ISA: /* ISA pin */
+ {
+ polarity = default_ISA_polarity(idx);
+ break;
+ }
+ case MP_BUS_EISA: /* EISA pin */
+ {
+ polarity = default_EISA_polarity(idx);
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ polarity = default_PCI_polarity(idx);
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ polarity = default_MCA_polarity(idx);
+ break;
+ }
+ default:
+ {
+ DPRINT("Broken BIOS!!\n");
+ polarity = 1;
+ break;
+ }
+ }
+ break;
+ }
+ case 1: /* high active */
+ {
+ polarity = 0;
+ break;
+ }
+ case 2: /* reserved */
+ {
+ DPRINT("Broken BIOS!!\n");
+ polarity = 1;
+ break;
+ }
+ case 3: /* low active */
+ {
+ polarity = 1;
+ break;
+ }
+ default: /* invalid */
+ {
+ DPRINT("Broken BIOS!!\n");
+ polarity = 1;
+ break;
+ }
+ }
+ return polarity;
+}
+
+static ULONG IRQTrigger(ULONG idx)
+{
+ ULONG bus = IRQMap[idx].SrcBusId;
+ ULONG trigger;
+
+ /*
+ * Determine IRQ trigger mode (edge or level sensitive):
+ */
+ switch ((IRQMap[idx].IrqFlag >> 2) & 3)
+ {
+ case 0: /* conforms, ie. bus-type dependent */
+ {
+ switch (BUSMap[bus])
+ {
+ case MP_BUS_ISA: /* ISA pin */
+ {
+ trigger = default_ISA_trigger(idx);
+ break;
+ }
+ case MP_BUS_EISA: /* EISA pin */
+ {
+ trigger = default_EISA_trigger(idx);
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ trigger = default_PCI_trigger(idx);
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ trigger = default_MCA_trigger(idx);
+ break;
+ }
+ default:
+ {
+ DPRINT("Broken BIOS!!\n");
+ trigger = 1;
+ break;
+ }
+ }
+ break;
+ }
+ case 1: /* edge */
+ {
+ trigger = 0;
+ break;
+ }
+ case 2: /* reserved */
+ {
+ DPRINT("Broken BIOS!!\n");
+ trigger = 1;
+ break;
+ }
+ case 3: /* level */
+ {
+ trigger = 1;
+ break;
+ }
+ default: /* invalid */
+ {
+ DPRINT("Broken BIOS!!\n");
+ trigger = 0;
+ break;
+ }
+ }
+ return trigger;
+}
+
+
+static ULONG Pin2Irq(ULONG idx,
+ ULONG apic,
+ ULONG pin)
+{
+ ULONG irq, i;
+ ULONG bus = IRQMap[idx].SrcBusId;
+
+ /*
+ * Debugging check, we are in big trouble if this message pops up!
+ */
+ if (IRQMap[idx].DstApicInt != pin) {
+ DPRINT("broken BIOS or MPTABLE parser, ayiee!!\n");
+ }
+
+ switch (BUSMap[bus])
+ {
+ case MP_BUS_ISA: /* ISA pin */
+ case MP_BUS_EISA:
+ case MP_BUS_MCA:
+ {
+ irq = IRQMap[idx].SrcBusIrq;
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ /*
+ * PCI IRQs are mapped in order
+ */
+ i = irq = 0;
+ while (i < apic)
+ irq += IOAPICMap[i++].EntryCount;
+ irq += pin;
+ break;
+ }
+ default:
+ {
+ DPRINT("Unknown bus type %d.\n",bus);
+ irq = 0;
+ break;
+ }
+ }
+
+ return irq;
+}
+
+
+/*
+ * Rough estimation of how many shared IRQs there are, can
+ * be changed anytime.
+ */
+#define MAX_PLUS_SHARED_IRQS PIC_IRQS
+#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + PIC_IRQS)
+
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * the indexing order of this array favors 1:1 mappings
+ * between pins and IRQs.
+ */
+
+static struct irq_pin_list {
+ ULONG apic, pin, next;
+} irq_2_pin[PIN_MAP_SIZE];
+
+/*
+ * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
+ * shared ISA-space IRQs, so we have to support them. We are super
+ * fast in the common case, and fast for shared ISA-space IRQs.
+ */
+static VOID AddPinToIrq(ULONG irq,
+ ULONG apic,
+ ULONG pin)
+{
+ static ULONG first_free_entry = PIC_IRQS;
+ struct irq_pin_list *entry = irq_2_pin + irq;
+
+ while (entry->next)
+ {
+ entry = irq_2_pin + entry->next;
+ }
+
+ if (entry->pin != -1)
+ {
+ entry->next = first_free_entry;
+ entry = irq_2_pin + entry->next;
+ if (++first_free_entry >= PIN_MAP_SIZE)
+ {
+ DPRINT1("Ohh no!");
+ KEBUGCHECK(0);
+ }
+ }
+ entry->apic = apic;
+ entry->pin = pin;
+}
+
+
+/*
+ * Find the IRQ entry number of a certain pin.
+ */
+static ULONG IOAPICGetIrqEntry(ULONG apic,
+ ULONG pin,
+ ULONG type)
+{
+ ULONG i;
+
+ for (i = 0; i < IRQCount; i++)
+ {
+ if (IRQMap[i].IrqType == type &&
+ (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
+ IRQMap[i].DstApicInt == pin)
+ {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
+static ULONG AssignIrqVector(ULONG irq)
+{
+#if 0
+ static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
+#endif
+ ULONG vector;
+ /* There may already have been assigned a vector for this IRQ */
+ vector = IRQVectorMap[irq];
+ if (vector > 0)
+ {
+ return vector;
+ }
+#if 0
+ if (current_vector > FIRST_SYSTEM_VECTOR) {
+ vector_offset++;
+ current_vector = FIRST_DEVICE_VECTOR + vector_offset;
+ } else if (current_vector == FIRST_SYSTEM_VECTOR) {
+ DPRINT1("Ran out of interrupt sources!");
+ KEBUGCHECK(0);
+ }
+
+ vector = current_vector;
+ IRQVectorMap[irq] = vector;
+ current_vector += 8;
+ return vector;
+#else
+ vector = IRQ2VECTOR(irq);
+ IRQVectorMap[irq] = vector;
+ return vector;
+#endif
+}
+
+
+VOID IOAPICSetupIrqs(VOID)
+{
+ IOAPIC_ROUTE_ENTRY entry;
+ ULONG apic, pin, idx, irq, first_notcon = 1, vector;
+
+ DPRINT("Init IO_APIC IRQs\n");
+
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+ for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++)
+ {
+ /*
+ * add it to the IO-APIC irq-routing table
+ */
+ memset(&entry,0,sizeof(entry));
+
+ entry.delivery_mode = APIC_DM_LOWEST;
+ entry.dest_mode = 1; /* logical delivery */
+ entry.mask = 1; /* disable IRQ */
+#if 0
+ /*
+ * FIXME:
+ * Some drivers are not able to deal with more than one cpu.
+ */
+ entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+ entry.dest.logical.logical_dest = 1 << 0;
+#endif
+ idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
+ if (idx == -1)
+ {
+ if (first_notcon)
+ {
+ DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
+ first_notcon = 0;
+ }
+ else
+ {
+ DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
+ }
+ continue;
+ }
+
+ entry.trigger = IRQTrigger(idx);
+ entry.polarity = IRQPolarity(idx);
+
+ if (entry.trigger)
+ {
+ entry.trigger = 1;
+ entry.mask = 1; // disable
+#if 0
+ entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+ entry.dest.logical.logical_dest = 1 << 0;
+#endif
+ }
+
+ irq = Pin2Irq(idx, apic, pin);
+ AddPinToIrq(irq, apic, pin);
+
+ vector = AssignIrqVector(irq);
+ entry.vector = vector;
+
+ DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
+
+ if (irq == 0)
+ {
+ /* Mask timer IRQ */
+ entry.mask = 1;
+ }
+
+ if ((apic == 0) && (irq < 16))
+ {
+ Disable8259AIrq(irq);
+ }
+ IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
+ IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
+
+ IrqPinMap[irq] = pin;
+ IrqApicMap[irq] = apic;
+
+ DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);
+ }
+ }
+}
+
+
+static VOID IOAPICEnable(VOID)
+{
+ ULONG i, tmp;
+
+ for (i = 0; i < PIN_MAP_SIZE; i++)
+ {
+ irq_2_pin[i].pin = -1;
+ irq_2_pin[i].next = 0;
+ }
+
+ /*
+ * The number of IO-APIC IRQ registers (== #pins):
+ */
+ for (i = 0; i < IOAPICCount; i++)
+ {
+ tmp = IOAPICRead(i, IOAPIC_VER);
+ IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
+ }
+
+ /*
+ * Do not trust the IO-APIC being empty at bootup
+ */
+ IOAPICClearAll();
+}
+
+#if 0
+static VOID IOAPICDisable(VOID)
+{
+ /*
+ * Clear the IO-APIC before rebooting
+ */
+ IOAPICClearAll();
+ APICDisable();
+}
+#endif
+
+
+static VOID IOAPICSetup(VOID)
+{
+ IOAPICEnable();
+ IOAPICSetupIds();
+ APICSyncArbIDs();
+ IOAPICSetupIrqs();
+}
+
+
+VOID IOAPICDump(VOID)
+{
+ ULONG apic, i;
+ ULONG reg0, reg1, reg2=0;
+
+ DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
+ for (i = 0; i < IOAPICCount; i++)
+ {
+ DbgPrint("Number of IO-APIC #%d registers: %d.\n",
+ IOAPICMap[i].ApicId,
+ IOAPICMap[i].EntryCount);
+ }
+
+ /*
+ * We are a bit conservative about what we expect. We have to
+ * know about every hardware change ASAP.
+ */
+ DbgPrint("Testing the IO APIC.......................\n");
+
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+ reg0 = IOAPICRead(apic, IOAPIC_ID);
+ reg1 = IOAPICRead(apic, IOAPIC_VER);
+ if (GET_IOAPIC_VERSION(reg1) >= 0x10)
+ {
+ reg2 = IOAPICRead(apic, IOAPIC_ARB);
+ }
+
+ DbgPrint("\n");
+ DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
+ DbgPrint(".... register #00: %08X\n", reg0);
+ DbgPrint("....... : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
+ if (reg0 & 0xF0FFFFFF)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ DbgPrint(".... register #01: %08X\n", reg1);
+ i = GET_IOAPIC_MRE(reg1);
+
+ DbgPrint("....... : max redirection entries: %04X\n", i);
+ if ((i != 0x0f) && /* older (Neptune) boards */
+ (i != 0x17) && /* typical ISA+PCI boards */
+ (i != 0x1b) && /* Compaq Proliant boards */
+ (i != 0x1f) && /* dual Xeon boards */
+ (i != 0x22) && /* bigger Xeon boards */
+ (i != 0x2E) &&
+ (i != 0x3F))
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ i = GET_IOAPIC_VERSION(reg1);
+ DbgPrint("....... : IO APIC version: %04X\n", i);
+ if ((i != 0x01) && /* 82489DX IO-APICs */
+ (i != 0x10) && /* oldest IO-APICs */
+ (i != 0x11) && /* Pentium/Pro IO-APICs */
+ (i != 0x13)) /* Xeon IO-APICs */
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ if (reg1 & 0xFF00FF00)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+
+ if (GET_IOAPIC_VERSION(reg1) >= 0x10)
+ {
+ DbgPrint(".... register #02: %08X\n", reg2);
+ DbgPrint("....... : arbitration: %02X\n",
+ GET_IOAPIC_ARB(reg2));
+ if (reg2 & 0xF0FFFFFF)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+ }
+
+ DbgPrint(".... IRQ redirection table:\n");
+ DbgPrint(" NR Log Phy Mask Trig IRR Pol"
+ " Stat Dest Deli Vect: \n");
+
+ for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++)
+ {
+ IOAPIC_ROUTE_ENTRY entry;
+
+ *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
+ *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
+
+ DbgPrint(" %02x %03X %02X ",
+ i,
+ entry.dest.logical.logical_dest,
+ entry.dest.physical.physical_dest);
+
+ DbgPrint("%C %C %1d %C %C %C %03X %02X\n",
+ (entry.mask == 0) ? 'U' : 'M', // Unmasked/masked
+ (entry.trigger == 0) ? 'E' : 'L', // Edge/level sensitive
+ entry.irr,
+ (entry.polarity == 0) ? 'H' : 'L', // Active high/active low
+ (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
+ (entry.dest_mode == 0) ? 'P' : 'L', // Physical logical
+ entry.delivery_mode,
+ entry.vector);
+ }
+ }
+ DbgPrint("IRQ to pin mappings:\n");
+ for (i = 0; i < PIC_IRQS; i++)
+ {
+ struct irq_pin_list *entry = irq_2_pin + i;
+ if (entry->pin < 0)
+ {
+ continue;
+ }
+ DbgPrint("IRQ%d ", i);
+ for (;;)
+ {
+ DbgPrint("-> %d", entry->pin);
+ if (!entry->next)
+ {
+ break;
+ }
+ entry = irq_2_pin + entry->next;
+ }
+ if (i % 2)
+ {
+ DbgPrint("\n");
+ }
+ else
+ {
+ DbgPrint(" ");
+ }
+ }
+
+ DbgPrint(".................................... done.\n");
+}
+
+
+
+/* Functions for handling local APICs */
+
+ULONG Read8254Timer(VOID)
+{
+ ULONG Count;
+
+ WRITE_PORT_UCHAR((PUCHAR)0x43, 0x00);
+ Count = READ_PORT_UCHAR((PUCHAR)0x40);
+ Count |= READ_PORT_UCHAR((PUCHAR)0x40) << 8;
+
+ return Count;
+}
+
+VOID WaitFor8254Wraparound(VOID)
+{
+ ULONG CurCount, PrevCount = ~0;
+ LONG Delta;
+
+ CurCount = Read8254Timer();
+ do
+ {
+ PrevCount = CurCount;
+ CurCount = Read8254Timer();
+ Delta = CurCount - PrevCount;
+
+ /*
+ * This limit for delta seems arbitrary, but it isn't, it's
+ * slightly above the level of error a buggy Mercury/Neptune
+ * chipset timer can cause.
+ */
+
+ }
+ while (Delta < 300);
+}
+
+#define HZ (100)
+#define APIC_DIVISOR (16)
+
+VOID APICSetupLVTT(ULONG ClockTicks)
+{
+ ULONG tmp;
+
+ tmp = GET_APIC_VERSION(APICRead(APIC_VER));
+ if (!APIC_INTEGRATED(tmp))
+ {
+ tmp = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) | APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+ }
+ else
+ {
+ /* Periodic timer */
+ tmp = APIC_LVT_PERIODIC | LOCAL_TIMER_VECTOR;;
+ }
+ APICWrite(APIC_LVTT, tmp);
+
+ tmp = APICRead(APIC_TDCR);
+ tmp &= ~(APIC_TDCR_1 | APIC_TIMER_BASE_DIV);
+ tmp |= APIC_TDCR_16;
+ APICWrite(APIC_TDCR, tmp);
+ APICWrite(APIC_ICRT, ClockTicks / APIC_DIVISOR);
+}
+
+
+VOID APICCalibrateTimer(ULONG CPU)
+{
+ ULARGE_INTEGER t1, t2;
+ LONG tt1, tt2;
+
+ DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
+
+ APICSetupLVTT(1000000000);
+
+ /*
+ * The timer chip counts down to zero. Let's wait
+ * for a wraparound to start exact measurement:
+ * (the current tick might have been already half done)
+ */
+ WaitFor8254Wraparound();
+
+ /*
+ * We wrapped around just now. Let's start
+ */
+ ReadPentiumClock(&t1);
+ tt1 = APICRead(APIC_CCRT);
+
+ WaitFor8254Wraparound();
+
+
+ tt2 = APICRead(APIC_CCRT);
+ ReadPentiumClock(&t2);
+
+ CPUMap[CPU].BusSpeed = (HZ * (long)(tt1 - tt2) * APIC_DIVISOR);
+ CPUMap[CPU].CoreSpeed = (HZ * (t2.QuadPart - t1.QuadPart));
+
+ /* Setup timer for normal operation */
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100); // 100ns
+ APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 10000); // 10ms
+// APICSetupLVTT((CPUMap[CPU].BusSpeed / 1000000) * 100000); // 100ms
+
+ DPRINT("CPU clock speed is %ld.%04ld MHz.\n",
+ CPUMap[CPU].CoreSpeed/1000000,
+ CPUMap[CPU].CoreSpeed%1000000);
+
+ DPRINT("Host bus clock speed is %ld.%04ld MHz.\n",
+ CPUMap[CPU].BusSpeed/1000000,
+ CPUMap[CPU].BusSpeed%1000000);
+}
+
+VOID
+SetInterruptGate(ULONG index, ULONG address)
+{
+ IDT_DESCRIPTOR *idt;
+
+ idt = (IDT_DESCRIPTOR*)((ULONG)KeGetCurrentKPCR()->IDT + index * sizeof(IDT_DESCRIPTOR));
+ idt->a = (((ULONG)address)&0xffff) + (KERNEL_CS << 16);
+ idt->b = 0x8e00 + (((ULONG)address)&0xffff0000);
+}
+
+VOID STDCALL
+HalInitializeProcessor(ULONG ProcessorNumber,
+ PVOID /*PLOADER_PARAMETER_BLOCK*/ LoaderBlock)
+{
+ ULONG CPU;
+
[truncated at 1000 lines; 811 more skipped]
reactos/hal/halx86/mp
diff -N resource_mp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ resource_mp.c 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,38 @@
+/* $Id: resource_mp.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/mp/resource_mp.c
+ * PURPOSE: Miscellaneous resource functions for MP
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ****************************************************************/
+
+VOID
+HaliReconfigurePciInterrupts(VOID);
+
+
+VOID STDCALL
+HalReportResourceUsage(VOID)
+{
+ /*
+ * FIXME: Report all resources used by hal.
+ * Calls IoReportHalResourceUsage()
+ */
+
+ /* Initialize PCI bus. */
+ HalpInitPciBus ();
+
+ HaliReconfigurePciInterrupts();
+}
+
+/* EOF */
reactos/hal/halx86/up
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map
reactos/hal/halx86/up
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 13 Dec 2004 16:18:24 -0000 1.4.2.1
@@ -0,0 +1,89 @@
+# $Id: Makefile,v 1.4.2.1 2004/12/13 16:18:24 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+TARGET_NAME = halup
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_BOOTSTRAP = yes
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DUP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DUP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+ifeq ($(MP), 1)
+TARGET_INSTALL = no
+else
+TARGET_BOOTSTRAP = yes
+endif
+
+GENERIC_OBJECTS = \
+ adapter.o \
+ beep.o \
+ bus.o \
+ display.o \
+ dma.o \
+ drive.o \
+ enum.o \
+ fmutex.o \
+ halinit.o \
+ ipi.o \
+ irql.o \
+ isa.o \
+ kdbg.o \
+ mca.o \
+ misc.o \
+ pci.o \
+ portio.o \
+ processor.o \
+ reboot.o \
+ resource.o \
+ spinlock.o \
+ sysbus.o \
+ sysinfo.o \
+ time.o \
+ timer.o
+
+UP_OBJECTS = \
+ halinit_up.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(UP_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF
reactos/hal/halx86/up
diff -N halinit_up.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit_up.c 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,31 @@
+/* $Id: halinit_up.c,v 1.1.2.1 2004/12/13 16:18:24 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+ HalpInitPICs();
+
+ /* Setup busy waiting */
+ HalpCalibrateStallExecution();
+}
+
+/* EOF */
reactos/hal/halx86/up
diff -N halup.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halup.rc 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "X86 Uniprocessor Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halup\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halup.dll\0"
+#include <reactos/version.rc>
reactos/hal/halx86/xbox
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:24 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+*.d
+*.dll
+*.coff
+*.a
+*.o
+*.sym
+*.map
reactos/hal/halx86/xbox
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 13 Dec 2004 16:18:25 -0000 1.4.2.1
@@ -0,0 +1,89 @@
+# $Id: Makefile,v 1.4.2.1 2004/12/13 16:18:25 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+VPATH = ../generic
+
+default: all
+
+TARGET_NAME = halxbox
+
+#
+# Build configuration
+#
+include $(PATH_TO_TOP)/rules.mak
+
+#
+# Global configuration
+#
+include $(TOOLS_PATH)/config.mk
+
+TARGET_BOOTSTRAP = yes
+
+TARGET_TYPE = hal
+
+TARGET_DEFNAME = ../../hal/hal
+
+TARGET_ASFLAGS = -I$(PATH_TO_TOP)/include -I$(PATH_TO_TOP)/ntoskrnl/include -D__ASM__ -DUP
+
+TARGET_CFLAGS = -I../include -I$(PATH_TO_TOP)/ntoskrnl/include -Wall -Werror -DUP
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS
+
+TARGET_INSTALL = no
+TARGET_BOOTSTRAP = no
+
+GENERIC_OBJECTS = \
+ adapter.o \
+ beep.o \
+ bus.o \
+ dma.o \
+ drive.o \
+ enum.o \
+ fmutex.o \
+ halinit.o \
+ ipi.o \
+ irql.o \
+ isa.o \
+ kdbg.o \
+ mca.o \
+ misc.o \
+ pci.o \
+ portio.o \
+ processor.o \
+ reboot.o \
+ resource.o \
+ spinlock.o \
+ sysbus.o \
+ sysinfo.o \
+ time.o \
+ timer.o
+
+XBOX_OBJECTS = \
+ display_xbox.o \
+ font.o \
+ halinit_xbox.o \
+ part_xbox.o \
+ pci_xbox.o
+
+HAL_OBJECTS = $(GENERIC_OBJECTS) $(XBOX_OBJECTS)
+
+DEP_OBJECTS := $(HAL_OBJECTS)
+
+TARGET_OBJECTS := $(DEP_OBJECTS) $(PATH_TO_TOP)/include/roscfg.h
+
+# Note: Must be = and not := since $(DEP_FILES) is assigned a value below
+TARGET_CLEAN = $(DEP_FILES) *.o *.dll
+
+#
+# Helper makefile
+#
+include $(TOOLS_PATH)/helper.mk
+
+#
+# Include automatic dependancy tracking
+#
+include $(TOOLS_PATH)/depend.mk
+
+# EOF
reactos/hal/halx86/xbox
diff -N display_xbox.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ display_xbox.c 13 Dec 2004 16:18:25 -0000 1.3.2.1
@@ -0,0 +1,520 @@
+/* $Id: display_xbox.c,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/xbox/display_xbox.c
+ * PURPOSE: Blue screen display
+ * PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
+ * UPDATE HISTORY:
+ * Created 08/10/99
+ * Modified for Xbox 2004/12/02 GvG
+ */
+
+/* For an explanation about display ownership see generic/display.c */
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include "halxbox.h"
+
+#define I2C_IO_BASE 0xc000
+
+#define CONTROL_FRAMEBUFFER_ADDRESS_OFFSET 0x600800
+
+#define MAKE_COLOR(Red, Green, Blue) (0xff000000 | (((Red) & 0xff) << 16) | (((Green) & 0xff) << 8) | ((Blue) & 0xff))
+
+/* Default to grey on blue */
+#define DEFAULT_FG_COLOR MAKE_COLOR(127, 127, 127)
+#define DEFAULT_BG_COLOR MAKE_COLOR(0, 0, 127)
+
+#define TAG_HALX TAG('H', 'A', 'L', 'X')
+
+/* VARIABLES ****************************************************************/
+
+static ULONG CursorX = 0; /* Cursor Position */
+static ULONG CursorY = 0;
+static ULONG SizeX; /* Display size (characters) */
+static ULONG SizeY;
+
+static BOOLEAN DisplayInitialized = FALSE;
+static BOOLEAN HalOwnsDisplay = TRUE;
+
+static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
+
+#define CHAR_WIDTH 8
+#define CHAR_HEIGHT 16
+
+static PVOID FrameBuffer;
+static ULONG BytesPerPixel;
+static ULONG Delta;
+
+/*
+ * It turns out that reading from the frame buffer is a pretty expensive
+ * operation. So, we're keeping shadow arrays of the contents and use
+ * those when needed (only for scrolling) instead of reading from the fb.
+ * This cuts down boot time from about 45 sec to about 6 sec.
+ */
+static PUCHAR CellContents;
+static PULONG CellFgColor;
+static PULONG CellBgColor;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+static VOID FASTCALL
+HalpXboxOutputChar(UCHAR Char, unsigned X, unsigned Y, ULONG FgColor, ULONG BgColor)
+{
+ PUCHAR FontPtr;
+ PULONG Pixel;
+ UCHAR Mask;
+ unsigned Line;
+ unsigned Col;
+
+ FontPtr = XboxFont8x16 + Char * 16;
+ Pixel = (PULONG) ((char *) FrameBuffer + Y * CHAR_HEIGHT * Delta
+ + X * CHAR_WIDTH * BytesPerPixel);
+ for (Line = 0; Line < CHAR_HEIGHT; Line++)
+ {
+ Mask = 0x80;
+ for (Col = 0; Col < CHAR_WIDTH; Col++)
+ {
+ Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
+ Mask = Mask >> 1;
+ }
+ Pixel = (PULONG) ((char *) Pixel + Delta);
+ }
+
+ if (NULL != CellContents)
+ {
+ CellContents[Y * SizeX + X] = Char;
+ CellFgColor[Y * SizeX + X] = FgColor;
+ CellBgColor[Y * SizeX + X] = BgColor;
+ }
+}
+
+static ULONG FASTCALL
+HalpXboxAttrToSingleColor(UCHAR Attr)
+{
+ UCHAR Intensity;
+
+ Intensity = (0 == (Attr & 0x08) ? 127 : 255);
+
+ return 0xff000000 |
+ (0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
+ (0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
+ (0 == (Attr & 0x01) ? 0 : Intensity);
+}
+
+static VOID FASTCALL
+HalpXboxAttrToColors(UCHAR Attr, ULONG *FgColor, ULONG *BgColor)
+{
+ *FgColor = HalpXboxAttrToSingleColor(Attr & 0xf);
+ *BgColor = HalpXboxAttrToSingleColor((Attr >> 4) & 0xf);
+}
+
+static VOID FASTCALL
+HalpXboxClearScreenColor(ULONG Color)
+{
+ ULONG Line, Col;
+ PULONG p;
+
+ for (Line = 0; Line < SizeY * CHAR_HEIGHT; Line++)
+ {
+ p = (PULONG) ((char *) FrameBuffer + Line * Delta);
+ for (Col = 0; Col < SizeX * CHAR_WIDTH; Col++)
+ {
+ *p++ = Color;
+ }
+ }
+
+ if (NULL != CellContents)
+ {
+ for (Line = 0; Line < SizeY; Line++)
+ {
+ for (Col = 0; Col < SizeX; Col++)
+ {
+ CellContents[Line * SizeX + Col] = ' ';
+ CellFgColor[Line * SizeX + Col] = Color;
+ CellBgColor[Line * SizeX + Col] = Color;
+ }
+ }
+ }
+}
+
+VOID FASTCALL
+HalClearDisplay(UCHAR CharAttribute)
+{
+ ULONG FgColor, BgColor;
+
+ HalpXboxAttrToColors(CharAttribute, &FgColor, &BgColor);
+
+ HalpXboxClearScreenColor(BgColor);
+
+ CursorX = 0;
+ CursorY = 0;
+}
+
+VOID STATIC
+HalScrollDisplay (VOID)
+{
+ ULONG Line, Col;
+ PULONG p;
+
+ if (NULL == CellContents)
+ {
+ p = (PULONG) ((char *) FrameBuffer + (Delta * CHAR_HEIGHT));
+ RtlMoveMemory(FrameBuffer,
+ p,
+ (Delta * CHAR_HEIGHT) * (SizeY - 1));
+
+ for (Line = 0; Line < CHAR_HEIGHT; Line++)
+ {
+ p = (PULONG) ((char *) FrameBuffer + (CHAR_HEIGHT * (SizeY - 1 ) + Line) * Delta);
+ for (Col = 0; Col < SizeX * CHAR_WIDTH; Col++)
+ {
+ *p++ = DEFAULT_BG_COLOR;
+ }
+ }
+ }
+ else
+ {
+ for (Line = 0; Line < SizeY - 1; Line++)
+ {
+ for (Col = 0; Col < SizeX; Col++)
+ {
+ HalpXboxOutputChar(CellContents[(Line + 1) * SizeX + Col], Col, Line,
+ CellFgColor[(Line + 1) * SizeX + Col],
+ CellBgColor[(Line + 1) * SizeX + Col]);
+ }
+ }
+ for (Col = 0; Col < SizeX; Col++)
+ {
+ HalpXboxOutputChar(' ', Col, SizeY - 1, DEFAULT_FG_COLOR, DEFAULT_BG_COLOR);
+ }
+ }
+}
+
+static VOID FASTCALL
+HalPutCharacter(UCHAR Character)
+{
+ HalpXboxOutputChar(Character, CursorX, CursorY, DEFAULT_FG_COLOR, DEFAULT_BG_COLOR);
+}
+
+static BOOL
+ReadfromSMBus(UCHAR Address, UCHAR bRegister, UCHAR Size, ULONG *Data_to_smbus)
+{
+ int nRetriesToLive=50;
+
+ while (0 != (READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0)) & 0x0800))
+ {
+ ; /* Franz's spin while bus busy with any master traffic */
+ }
+
+ while (0 != nRetriesToLive--)
+ {
+ UCHAR b;
+ int temp;
+
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 4), (Address << 1) | 1);
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 8), bRegister);
+
+ temp = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0));
+ WRITE_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 0), temp); /* clear down all preexisting errors */
+
+ switch (Size)
+ {
+ case 4:
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0d); /* DWORD modus ? */
+ break;
+ case 2:
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0b); /* WORD modus */
+ break;
+ default:
+ WRITE_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 2), 0x0a); // BYTE
+ break;
+ }
+
+ b = 0;
+
+ while (0 == (b & 0x36))
+ {
+ b = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 0));
+ }
+
+ if (0 != (b & 0x24))
+ {
+ /* printf("I2CTransmitByteGetReturn error %x\n", b); */
+ }
+
+ if(0 == (b & 0x10))
+ {
+ /* printf("I2CTransmitByteGetReturn no complete, retry\n"); */
+ }
+ else
+ {
+ switch (Size)
+ {
+ case 4:
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 9));
+ break;
+ case 2:
+ *Data_to_smbus = READ_PORT_USHORT((PUSHORT) (I2C_IO_BASE + 6));
+ break;
+ default:
+ *Data_to_smbus = READ_PORT_UCHAR((PUCHAR) (I2C_IO_BASE + 6));
+ break;
+ }
+
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static BOOL
+I2CTransmitByteGetReturn(UCHAR bPicAddressI2cFormat, UCHAR bDataToWrite, ULONG *Return)
+{
+ return ReadfromSMBus(bPicAddressI2cFormat, bDataToWrite, 1, Return);
+}
+
+VOID FASTCALL
+HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
+/*
+ * FUNCTION: Initalize the display
+ * ARGUMENTS:
+ * InitParameters = Parameters setup by the boot loader
+ */
+{
+ ULONG ScreenWidthPixels;
+ ULONG ScreenHeightPixels;
+ PHYSICAL_ADDRESS PhysControl;
+ PHYSICAL_ADDRESS PhysBuffer;
+ ULONG AvMode;
+ PVOID ControlBuffer;
+
+ if (! DisplayInitialized)
+ {
+ PhysBuffer.u.HighPart = 0;
+ if (0 != (LoaderBlock->Flags & MB_FLAGS_MEM_INFO))
+ {
+ PhysBuffer.u.LowPart = (LoaderBlock->MemHigher + 1024) * 1024;
+ }
+ else
+ {
+ /* Assume a 64Mb Xbox, last 4MB for video buf */
+ PhysBuffer.u.LowPart = 60 * 1024 * 1024;
+ }
+ PhysBuffer.u.LowPart |= 0xf0000000;
+
+ /* Tell the nVidia controller about the framebuffer */
+ PhysControl.u.HighPart = 0;
+ PhysControl.u.LowPart = 0xfd000000;
+ ControlBuffer = MmMapIoSpace(PhysControl, 0x1000000, MmNonCached);
+ if (NULL == ControlBuffer)
+ {
+ return;
+ }
+ *((PULONG) ((char *) ControlBuffer + CONTROL_FRAMEBUFFER_ADDRESS_OFFSET)) = (ULONG) PhysBuffer.u.LowPart;
+ MmUnmapIoSpace(ControlBuffer, 0x1000000);
+
+ FrameBuffer = MmMapIoSpace(PhysBuffer, 4 * 1024 * 1024, MmNonCached);
+ if (NULL == FrameBuffer)
+ {
+ return;
+ }
+
+ if (I2CTransmitByteGetReturn(0x10, 0x04, &AvMode))
+ {
+ if (1 == AvMode) /* HDTV */
+ {
+ ScreenWidthPixels = 720;
+ }
+ else
+ {
+ /* FIXME Other possible values of AvMode:
+ * 0 - AV_SCART_RGB
+ * 2 - AV_VGA_SOG
+ * 4 - AV_SVIDEO
+ * 6 - AV_COMPOSITE
+ * 7 - AV_VGA
+ * other AV_COMPOSITE
+ */
+ ScreenWidthPixels = 640;
+ }
+ }
+ else
+ {
+ ScreenWidthPixels = 640;
+ }
+ ScreenHeightPixels = 480;
+ BytesPerPixel = 4;
+
+ SizeX = ScreenWidthPixels / CHAR_WIDTH;
+ SizeY = ScreenHeightPixels / CHAR_HEIGHT;
+ Delta = (ScreenWidthPixels * BytesPerPixel + 3) & ~ 0x3;
+
+ CellFgColor = (PULONG) ExAllocatePoolWithTag(PagedPool,
+ SizeX * SizeY * (sizeof(ULONG) + sizeof(ULONG) + sizeof(UCHAR)),
+ TAG_HALX);
+ if (NULL != CellFgColor)
+ {
+ CellBgColor = CellFgColor + SizeX * SizeY;
+ CellContents = (PUCHAR) (CellBgColor + SizeX * SizeY);
+ }
+ else
+ {
+ CellBgColor = NULL;
+ CellContents = NULL;
+ }
+
+ HalpXboxClearScreenColor(MAKE_COLOR(0, 0, 0));
+
+ DisplayInitialized = TRUE;
+ }
+}
+
+
+/* PUBLIC FUNCTIONS *********************************************************/
+
+VOID STDCALL
+HalReleaseDisplayOwnership(VOID)
+/*
+ * FUNCTION: Release ownership of display back to HAL
+ */
+{
+ if (HalOwnsDisplay || NULL == HalResetDisplayParameters)
+ {
+ return;
+ }
+
+ HalResetDisplayParameters(SizeX, SizeY);
+
+ HalOwnsDisplay = TRUE;
+ HalpXboxClearScreenColor(DEFAULT_BG_COLOR);
+
+ CursorX = 0;
+ CursorY = 0;
+}
+
+
+VOID STDCALL
+HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * ResetDisplayParameters = Pointer to a driver specific
+ * reset routine.
+ */
+{
+ HalOwnsDisplay = FALSE;
+ HalResetDisplayParameters = ResetDisplayParameters;
+}
+
+VOID STDCALL
+HalDisplayString(IN PCH String)
+/*
+ * FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
+ * already and displays a string
+ * ARGUMENT:
+ * string = ASCII string to display
+ * NOTE: Use with care because there is no support for returning from BSOD
+ * mode
+ */
+{
+ PCH pch;
+ static KSPIN_LOCK Lock;
+ KIRQL OldIrql;
+ ULONG Flags;
+
+ if (! HalOwnsDisplay || ! DisplayInitialized)
+ {
+ return;
+ }
+
+ pch = String;
+
+ OldIrql = KfRaiseIrql(HIGH_LEVEL);
+ KiAcquireSpinLock(&Lock);
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+
+ while (*pch != 0)
+ {
+ if (*pch == '\n')
+ {
+ CursorY++;
+ CursorX = 0;
+ }
+ else if (*pch == '\b')
+ {
+ if (CursorX > 0)
+ {
+ CursorX--;
+ }
+ }
+ else if (*pch != '\r')
+ {
+ HalPutCharacter(*pch);
+ CursorX++;
+
+ if (SizeX <= CursorX)
+ {
+ CursorY++;
+ CursorX = 0;
+ }
+ }
+
+ if (SizeY <= CursorY)
+ {
+ HalScrollDisplay ();
+ CursorY = SizeY - 1;
+ }
+
+ pch++;
+ }
+
+ Ki386RestoreFlags(Flags);
+
+ KiReleaseSpinLock(&Lock);
+ KfLowerIrql(OldIrql);
+}
+
+VOID STDCALL
+HalQueryDisplayParameters(OUT PULONG DispSizeX,
+ OUT PULONG DispSizeY,
+ OUT PULONG CursorPosX,
+ OUT PULONG CursorPosY)
+{
+ if (DispSizeX)
+ *DispSizeX = SizeX;
+ if (DispSizeY)
+ *DispSizeY = SizeY;
+ if (CursorPosX)
+ *CursorPosX = CursorX;
+ if (CursorPosY)
+ *CursorPosY = CursorY;
+}
+
+
+VOID STDCALL
+HalSetDisplayParameters(IN ULONG CursorPosX,
+ IN ULONG CursorPosY)
+{
+ CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
+ CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
+}
+
+
+BOOLEAN STDCALL
+HalQueryDisplayOwnership(VOID)
+{
+ return ! HalOwnsDisplay;
+}
+
+/* EOF */
reactos/hal/halx86/xbox
diff -N font.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ font.c 13 Dec 2004 16:18:25 -0000 1.1.2.1
@@ -0,0 +1,281 @@
+/* $Id: font.c,v 1.1.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Xbox HAL
+ * FILE: hal/halx86/xbox/font.h
+ * PURPOSE: Font glyphs
+ * PROGRAMMER: Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ * Created 2004/12/02
+ *
+ * Note: Converted from the XFree vga.bdf font
+ */
+
+#include <ddk/ntddk.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+BYTE XboxFont8x16[256 * 16] =
+{
+ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* 0x00 */
+ 0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xa5,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, /* 0x01 */
+ 0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xdb,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, /* 0x02 */
+ 0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, /* 0x03 */
+ 0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x04 */
+ 0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x05 */
+ 0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x06 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x07 */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, /* 0x08 */
+ 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, /* 0x09 */
+ 0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, /* 0x0a */
+ 0x00,0x00,0x1e,0x06,0x0e,0x1a,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* 0x0b */
+ 0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0c */
+ 0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, /* 0x0d */
+ 0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, /* 0x0e */
+ 0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x0f */
+ 0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, /* 0x10 */
+ 0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* 0x11 */
+ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, /* 0x12 */
+ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, /* 0x13 */
+ 0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, /* 0x14 */
+ 0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, /* 0x15 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, /* 0x16 */
+ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0x17 */
+ 0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x18 */
+ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0x19 */
+ 0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1a */
+ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1b */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1c */
+ 0x00,0x00,0x00,0x00,0x00,0x28,0x6c,0xfe,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00, /* 0x1d */
+ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x1e */
+ 0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, /* 0x1f */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* */
+ 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ! */
+ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* " */
+ 0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, /* # */
+ 0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, /* $ */
+ 0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, /* % */
+ 0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* & */
+ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ' */
+ 0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, /* ( */
+ 0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, /* ) */
+ 0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, /* * */
+ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* + */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, /* , */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* . */
+ 0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, /* / */
+ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xd6,0xd6,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0 */
+ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, /* 1 */
+ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 2 */
+ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 3 */
+ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, /* 4 */
+ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 5 */
+ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 6 */
+ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, /* 7 */
+ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 8 */
+ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, /* 9 */
+ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* : */
+ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, /* ; */
+ 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, /* < */
+ 0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* = */
+ 0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, /* > */
+ 0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, /* ? */
+ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, /* @ */
+ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* A */
+ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, /* B */
+ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, /* C */
+ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, /* D */
+ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* E */
+ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* F */
+ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, /* G */
+ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* H */
+ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* I */
+ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, /* J */
+ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* K */
+ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, /* L */
+ 0x00,0x00,0xc6,0xee,0xfe,0xfe,0xd6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* M */
+ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* N */
+ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* O */
+ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* P */
+ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, /* Q */
+ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* R */
+ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* S */
+ 0x00,0x00,0x7e,0x7e,0x5a,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* T */
+ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* U */
+ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x6c,0x38,0x10,0x00,0x00,0x00,0x00, /* V */
+ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0xee,0x6c,0x00,0x00,0x00,0x00, /* W */
+ 0x00,0x00,0xc6,0xc6,0x6c,0x7c,0x38,0x38,0x7c,0x6c,0xc6,0xc6,0x00,0x00,0x00,0x00, /* X */
+ 0x00,0x00,0x66,0x66,0x66,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* Y */
+ 0x00,0x00,0xfe,0xc6,0x86,0x0c,0x18,0x30,0x60,0xc2,0xc6,0xfe,0x00,0x00,0x00,0x00, /* Z */
+ 0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, /* [ */
+ 0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, /* \ */
+ 0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, /* ] */
+ 0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, /* _ */
+ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ` */
+ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* a */
+ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, /* b */
+ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* c */
+ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* d */
+ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* e */
+ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* f */
+ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, /* g */
+ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, /* h */
+ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* i */
+ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, /* j */
+ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, /* k */
+ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* l */
+ 0x00,0x00,0x00,0x00,0x00,0xec,0xfe,0xd6,0xd6,0xd6,0xd6,0xc6,0x00,0x00,0x00,0x00, /* m */
+ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* n */
+ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* o */
+ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, /* p */
+ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, /* q */
+ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, /* r */
+ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, /* s */
+ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, /* t */
+ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* u */
+ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, /* v */
+ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xd6,0xd6,0xd6,0xfe,0x6c,0x00,0x00,0x00,0x00, /* w */
+ 0x00,0x00,0x00,0x00,0x00,0xc6,0x6c,0x38,0x38,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00, /* x */
+ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, /* y */
+ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* z */
+ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, /* { */
+ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* | */
+ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, /* } */
+ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ~ */
+ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0x7f */
+ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, /* 0x80 */
+ 0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x81 */
+ 0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x82 */
+ 0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x83 */
+ 0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x84 */
+ 0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x85 */
+ 0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x86 */
+ 0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, /* 0x87 */
+ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x88 */
+ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x89 */
+ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x8a */
+ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8b */
+ 0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8c */
+ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0x8d */
+ 0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8e */
+ 0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0x8f */
+ 0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, /* 0x90 */
+ 0x00,0x00,0x00,0x00,0x00,0xcc,0x76,0x36,0x7e,0xd8,0xd8,0x6e,0x00,0x00,0x00,0x00, /* 0x91 */
+ 0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, /* 0x92 */
+ 0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x93 */
+ 0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x94 */
+ 0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x95 */
+ 0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x96 */
+ 0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0x97 */
+ 0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, /* 0x98 */
+ 0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x99 */
+ 0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0x9a */
+ 0x00,0x18,0x18,0x3c,0x66,0x60,0x60,0x60,0x66,0x3c,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9b */
+ 0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, /* 0x9c */
+ 0x00,0x00,0x66,0x66,0x3c,0x18,0x7e,0x18,0x7e,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0x9d */
+ 0x00,0xf8,0xcc,0xcc,0xf8,0xc4,0xcc,0xde,0xcc,0xcc,0xcc,0xc6,0x00,0x00,0x00,0x00, /* 0x9e */
+ 0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, /* 0x9f */
+ 0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa0 */
+ 0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, /* 0xa1 */
+ 0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa2 */
+ 0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, /* 0xa3 */
+ 0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, /* 0xa4 */
+ 0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xa5 */
+ 0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa6 */
+ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xa7 */
+ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, /* 0xa8 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, /* 0xa9 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, /* 0xaa */
+ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xdc,0x86,0x0c,0x18,0x3e,0x00,0x00, /* 0xab */
+ 0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x9e,0x3e,0x06,0x06,0x00,0x00, /* 0xac */
+ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, /* 0xad */
+ 0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xae */
+ 0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xaf */
+ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, /* 0xb0 */
+ 0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, /* 0xb1 */
+ 0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, /* 0xb2 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb3 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb4 */
+ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb5 */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb6 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb7 */
+ 0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xb8 */
+ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xb9 */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xba */
+ 0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xbb */
+ 0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbc */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbd */
+ 0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xbe */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xbf */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc0 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc1 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc2 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc3 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc4 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc5 */
+ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xc6 */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc7 */
+ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xc8 */
+ 0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xc9 */
+ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xca */
+ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcb */
+ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xcc */
+ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcd */
+ 0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xce */
+ 0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xcf */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd0 */
+ 0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd1 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd2 */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd3 */
+ 0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd4 */
+ 0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd5 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd6 */
+ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, /* 0xd7 */
+ 0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xd8 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xd9 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xda */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdb */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, /* 0xdc */
+ 0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, /* 0xdd */
+ 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, /* 0xde */
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xdf */
+ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, /* 0xe0 */
+ 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, /* 0xe1 */
+ 0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, /* 0xe2 */
+ 0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, /* 0xe3 */
+ 0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, /* 0xe4 */
+ 0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xe5 */
+ 0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, /* 0xe6 */
+ 0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, /* 0xe7 */
+ 0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, /* 0xe8 */
+ 0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, /* 0xe9 */
+ 0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, /* 0xea */
+ 0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, /* 0xeb */
+ 0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xec */
+ 0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, /* 0xed */
+ 0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, /* 0xee */
+ 0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, /* 0xef */
+ 0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, /* 0xf0 */
+ 0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, /* 0xf1 */
+ 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf2 */
+ 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, /* 0xf3 */
+ 0x00,0x00,0x0e,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0xf4 */
+ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, /* 0xf5 */
+ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, /* 0xf6 */
+ 0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf7 */
+ 0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf8 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xf9 */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfa */
+ 0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, /* 0xfb */
+ 0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfc */
+ 0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0xfd */
+ 0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, /* 0xfe */
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 /* 0xff */
+};
+
+/* EOF */
+
reactos/hal/halx86/xbox
diff -N halinit_xbox.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halinit_xbox.c 13 Dec 2004 16:18:25 -0000 1.3.2.1
@@ -0,0 +1,36 @@
+/* $Id: halinit_xbox.c,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/hal/x86/halinit.c
+ * PURPOSE: Initalize the x86 hal
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * 11/06/98: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+HalpInitPhase0(VOID)
+{
+ HalpHooks.InitPciBus = HalpXboxInitPciBus;
+
+ HalpInitPICs();
+
+ /* Setup busy waiting */
+ HalpCalibrateStallExecution();
+
+ HalpXboxInitPartIo();
+}
+
+/* EOF */
reactos/hal/halx86/xbox
diff -N halxbox.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halxbox.h 13 Dec 2004 16:18:25 -0000 1.3.2.1
@@ -0,0 +1,22 @@
+/* $Id: halxbox.h,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: Xbox HAL
+ * FILE: hal/halx86/xbox/halxbox.h
+ * PURPOSE: Xbox specific routines
+ * PROGRAMMER: Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ * Created 2004/12/02
+ */
+
+#ifndef HALXBOX_H_INCLUDED
+#define HALXBOX_H_INCLUDED
+
+extern BYTE XboxFont8x16[256 * 16];
+
+void HalpXboxInitPciBus(ULONG BusNumber, PBUS_HANDLER BusHandler);
+void HalpXboxInitPartIo(void);
+
+#endif /* HALXBOX_H_INCLUDED */
+
+/* EOF */
reactos/hal/halx86/xbox
diff -N halxbox.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ halxbox.rc 13 Dec 2004 16:18:25 -0000 1.1.2.1
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "Xbox Hardware Abstraction Layer\0"
+#define REACTOS_STR_INTERNAL_NAME "halxbox\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "halxbox.dll\0"
+#include <reactos/version.rc>
reactos/hal/halx86/xbox
diff -N part_xbox.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ part_xbox.c 13 Dec 2004 16:18:25 -0000 1.1.2.1
@@ -0,0 +1,322 @@
+/* $Id: part_xbox.c,v 1.1.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/xbox/part_xbox.c
+ * PURPOSE: Xbox specific handling of partition tables
+ * PROGRAMMER: Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ * 2004/12/04: Created
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#define XBOX_SIGNATURE_SECTOR 3
+#define XBOX_SIGNATURE ('B' | ('R' << 8) | ('F' << 16) | ('R' << 24))
+#define PARTITION_SIGNATURE 0xaa55
+
+/* VARIABLES ***************************************************************/
+
+static pHalExamineMBR NtoskrnlExamineMBR;
+static pHalIoReadPartitionTable NtoskrnlIoReadPartitionTable;
+static pHalIoSetPartitionInformation NtoskrnlIoSetPartitionInformation;
+static pHalIoWritePartitionTable NtoskrnlIoWritePartitionTable;
+
+static struct
+{
+ ULONG SectorStart;
+ ULONG SectorCount;
+ BYTE PartitionType;
+} XboxPartitions[] =
+{
+ /* This is in the \Device\Harddisk0\Partition.. order used by the Xbox kernel */
+ { 0x0055F400, 0x0098f800, PARTITION_FAT32 }, /* Store, E: */
+ { 0x00465400, 0x000FA000, PARTITION_FAT_16 }, /* System, C: */
+ { 0x00000400, 0x00177000, PARTITION_FAT_16 }, /* Cache1, X: */
+ { 0x00177400, 0x00177000, PARTITION_FAT_16 }, /* Cache2, Y: */
+ { 0x002EE400, 0x00177000, PARTITION_FAT_16 } /* Cache3, Z: */
+};
+
+#define XBOX_PARTITION_COUNT (sizeof(XboxPartitions) / sizeof(XboxPartitions[0]))
+
+/* FUNCTIONS ***************************************************************/
+
+
+static NTSTATUS
+HalpXboxReadSector(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN PLARGE_INTEGER SectorOffset,
+ IN PVOID Sector)
+{
+ IO_STATUS_BLOCK StatusBlock;
+ KEVENT Event;
+ PIRP Irp;
+ NTSTATUS Status;
+
+ DPRINT("HalpXboxReadSector(%p %lu 0x%08x%08x %p)\n",
+ DeviceObject, SectorSize, SectorOffset->u.HighPart, SectorOffset->u.LowPart, Sector);
+
+ ASSERT(DeviceObject);
+ ASSERT(Sector);
+
+ KeInitializeEvent(&Event,
+ NotificationEvent,
+ FALSE);
+
+ /* Read the sector */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
+ DeviceObject,
+ Sector,
+ SectorSize,
+ SectorOffset,
+ &Event,
+ &StatusBlock);
+
+ Status = IoCallDriver(DeviceObject,
+ Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Reading sector failed (Status 0x%08lx)\n",
+ Status);
+ return Status;
+ }
+
+ return Status;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxDeviceHasXboxPartitioning(PDEVICE_OBJECT DeviceObject,
+ ULONG SectorSize,
+ BOOLEAN *HasXboxPartitioning)
+{
+ PVOID SectorData;
+ LARGE_INTEGER Offset;
+ NTSTATUS Status;
+
+ DPRINT("HalpXboxDeviceHasXboxPartitioning(%p %lu %p)\n",
+ DeviceObject,
+ SectorSize,
+ HasXboxPartitioning);
+
+ SectorData = ExAllocatePool(PagedPool, SectorSize);
+ if (NULL == SectorData)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ Offset.QuadPart = XBOX_SIGNATURE_SECTOR * SectorSize;
+ Status = HalpXboxReadSector(DeviceObject, SectorSize, &Offset, SectorData);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ DPRINT("Signature 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ *((UCHAR *) SectorData), *((UCHAR *) SectorData + 1), *((UCHAR *) SectorData + 2), *((UCHAR *) SectorData + 3));
+ *HasXboxPartitioning = (XBOX_SIGNATURE == *((ULONG *) SectorData));
+ ExFreePool(SectorData);
+ DPRINT("%s partitioning found\n", *HasXboxPartitioning ? "Xbox" : "MBR");
+
+ return STATUS_SUCCESS;
+}
+
+static VOID FASTCALL
+HalpXboxExamineMBR(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN ULONG MBRTypeIdentifier,
+ OUT PVOID *Buffer)
+{
+ BOOLEAN HasXboxPartitioning;
+ NTSTATUS Status;
+
+ DPRINT("HalpXboxExamineMBR(%p %lu %lx %p)\n",
+ DeviceObject,
+ SectorSize,
+ MBRTypeIdentifier,
+ Buffer);
+
+ *Buffer = NULL;
+
+ Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+ if (! NT_SUCCESS(Status))
+ {
+ return;
+ }
+
+ if (! HasXboxPartitioning)
+ {
+ DPRINT("Delegating to standard MBR code\n");
+ NtoskrnlExamineMBR(DeviceObject, SectorSize, MBRTypeIdentifier, Buffer);
+ return;
+ }
+
+ /* Buffer already set to NULL */
+ return;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxIoReadPartitionTable(PDEVICE_OBJECT DeviceObject,
+ ULONG SectorSize,
+ BOOLEAN ReturnRecognizedPartitions,
+ PDRIVE_LAYOUT_INFORMATION *PartitionBuffer)
+{
+ BOOLEAN HasXboxPartitioning;
+ NTSTATUS Status;
+ unsigned Part;
+ PPARTITION_INFORMATION PartInfo;
+
+ DPRINT("HalpXboxIoReadPartitionTable(%p %lu %x %p)\n",
+ DeviceObject,
+ SectorSize,
+ ReturnRecognizedPartitions,
+ PartitionBuffer);
+
+ Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (! HasXboxPartitioning)
+ {
+ DPRINT("Delegating to standard MBR code\n");
+ return NtoskrnlIoReadPartitionTable(DeviceObject, SectorSize,
+ ReturnRecognizedPartitions, PartitionBuffer);
+ }
+
+ *PartitionBuffer = (PDRIVE_LAYOUT_INFORMATION)
+ ExAllocatePool(PagedPool,
+ sizeof(DRIVE_LAYOUT_INFORMATION) +
+ XBOX_PARTITION_COUNT * sizeof(PARTITION_INFORMATION));
+ if (NULL == *PartitionBuffer)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ (*PartitionBuffer)->PartitionCount = XBOX_PARTITION_COUNT;
+ (*PartitionBuffer)->Signature = PARTITION_SIGNATURE;
+ for (Part = 0; Part < XBOX_PARTITION_COUNT; Part++)
+ {
+ PartInfo = (*PartitionBuffer)->PartitionEntry + Part;
+ PartInfo->StartingOffset.QuadPart = (ULONGLONG) XboxPartitions[Part].SectorStart *
+ (ULONGLONG) SectorSize;
+ PartInfo->PartitionLength.QuadPart = (ULONGLONG) XboxPartitions[Part].SectorCount *
+ (ULONGLONG) SectorSize;
+ PartInfo->HiddenSectors = 0;
+ PartInfo->PartitionNumber = Part + 1;
+ PartInfo->PartitionType = XboxPartitions[Part].PartitionType;
+ PartInfo->BootIndicator = FALSE;
+ PartInfo->RecognizedPartition = TRUE;
+ PartInfo->RewritePartition = FALSE;
+ DPRINT(" %ld: nr: %d boot: %1x type: %x start: 0x%I64x count: 0x%I64x rec: %d\n",
+ Part,
+ PartInfo->PartitionNumber,
+ PartInfo->BootIndicator,
+ PartInfo->PartitionType,
+ PartInfo->StartingOffset.QuadPart,
+ PartInfo->PartitionLength.QuadPart,
+ PartInfo->RecognizedPartition);
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxIoSetPartitionInformation(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN ULONG PartitionNumber,
+ IN ULONG PartitionType)
+{
+ BOOLEAN HasXboxPartitioning;
+ NTSTATUS Status;
+
+ DPRINT("HalpXboxIoSetPartitionInformation(%p %lu %lu %lu)\n",
+ DeviceObject,
+ SectorSize,
+ PartitionNumber,
+ PartitionType);
+
+ Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (! HasXboxPartitioning)
+ {
+ DPRINT("Delegating to standard MBR code\n");
+ return NtoskrnlIoSetPartitionInformation(DeviceObject, SectorSize,
+ PartitionNumber, PartitionType);
+ }
+
+ /* Can't change the partitioning */
+ DPRINT1("Xbox partitions are fixed, can't change them\n");
+ return STATUS_ACCESS_DENIED;
+}
+
+static NTSTATUS FASTCALL
+HalpXboxIoWritePartitionTable(IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG SectorSize,
+ IN ULONG SectorsPerTrack,
+ IN ULONG NumberOfHeads,
+ IN PDRIVE_LAYOUT_INFORMATION PartitionBuffer)
+{
+ BOOLEAN HasXboxPartitioning;
+ NTSTATUS Status;
+
+ DPRINT("HalpXboxIoWritePartitionTable(%p %lu %lu %lu %p)\n",
+ DeviceObject,
+ SectorSize,
+ SectorsPerTrack,
+ NumberOfHeads,
+ PartitionBuffer);
+
+ Status = HalpXboxDeviceHasXboxPartitioning(DeviceObject, SectorSize, &HasXboxPartitioning);
+ if (! NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ if (! HasXboxPartitioning)
+ {
+ DPRINT("Delegating to standard MBR code\n");
+ return NtoskrnlIoWritePartitionTable(DeviceObject, SectorSize,
+ SectorsPerTrack, NumberOfHeads,
+ PartitionBuffer);
+ }
+
+ /* Can't change the partitioning */
+ DPRINT1("Xbox partitions are fixed, can't change them\n");
+ return STATUS_ACCESS_DENIED;
+}
+
+void
+HalpXboxInitPartIo(void)
+{
+ NtoskrnlExamineMBR = HalExamineMBR;
+ HalExamineMBR = HalpXboxExamineMBR;
+ NtoskrnlIoReadPartitionTable = HalIoReadPartitionTable;
+ HalIoReadPartitionTable = HalpXboxIoReadPartitionTable;
+ NtoskrnlIoSetPartitionInformation = HalIoSetPartitionInformation;
+ HalIoSetPartitionInformation = HalpXboxIoSetPartitionInformation;
+ NtoskrnlIoWritePartitionTable = HalIoWritePartitionTable;
+ HalIoWritePartitionTable = HalpXboxIoWritePartitionTable;
+}
+
+/* EOF */
reactos/hal/halx86/xbox
diff -N pci_xbox.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ pci_xbox.c 13 Dec 2004 16:18:25 -0000 1.3.2.1
@@ -0,0 +1,112 @@
+/* $Id: pci_xbox.c,v 1.3.2.1 2004/12/13 16:18:25 hyperion Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: hal/halx86/xbox/pci_xbox.c
+ * PURPOSE: Xbox specific handling of PCI cards
+ * PROGRAMMER: Ge van Geldorp (gvg@reactos.com)
+ * UPDATE HISTORY:
+ * 2004/12/04: Created
+ *
+ * Trying to get PCI config data from devices 0:0:1 and 0:0:2 will completely
+ * hang the Xbox. Also, the device number doesn't seem to be decoded for the
+ * video card, so it appears to be present on 1:0:0 - 1:31:0.
+ * We hack around these problems by indicating "device not present" for devices
+ * 0:0:1, 0:0:2, 1:1:0, 1:2:0, 1:3:0, ...., 1:31:0
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <hal.h>
+#include <bus.h>
+#include "halxbox.h"
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* VARIABLES ***************************************************************/
+
+static ULONG (STDCALL *GenericGetPciData)(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length);
+static ULONG (STDCALL *GenericSetPciData)(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length);
+
+/* FUNCTIONS ***************************************************************/
+
+static ULONG STDCALL
+HalpXboxGetPciData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ DPRINT("HalpXboxGetPciData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((0 == BusNumber && 0 == (SlotNumber & 0x1f) &&
+ (1 == ((SlotNumber >> 5) & 0x07) || 2 == ((SlotNumber >> 5) & 0x07))) ||
+ (1 == BusNumber && 0 != (SlotNumber & 0x1f)))
+ {
+ DPRINT("Blacklisted PCI slot\n");
+ if (0 == Offset && 2 <= Length)
+ {
+ *(PUSHORT)Buffer = PCI_INVALID_VENDORID;
+ return 2;
+ }
+ return 0;
+ }
+
+ return GenericGetPciData(BusHandler, BusNumber, SlotNumber, Buffer, Offset, Length);
+}
+
+static ULONG STDCALL
+HalpXboxSetPciData(PBUS_HANDLER BusHandler,
+ ULONG BusNumber,
+ ULONG SlotNumber,
+ PVOID Buffer,
+ ULONG Offset,
+ ULONG Length)
+{
+ DPRINT("HalpXboxSetPciData() called.\n");
+ DPRINT(" BusNumber %lu\n", BusNumber);
+ DPRINT(" SlotNumber %lu\n", SlotNumber);
+ DPRINT(" Offset 0x%lx\n", Offset);
+ DPRINT(" Length 0x%lx\n", Length);
+
+ if ((0 == BusNumber && 0 == (SlotNumber & 0x1f) &&
+ (1 == ((SlotNumber >> 5) & 0x07) || 2 == ((SlotNumber >> 5) & 0x07))) ||
+ (1 == BusNumber && 0 != (SlotNumber & 0x1f)))
+ {
+ DPRINT1("Trying to set data on blacklisted PCI slot\n");
+ return 0;
+ }
+
+ return GenericSetPciData(BusHandler, BusNumber, SlotNumber, Buffer, Offset, Length);
+}
+
+void
+HalpXboxInitPciBus(ULONG BusNumber, PBUS_HANDLER BusHandler)
+{
+ if (0 == BusNumber || 1 == BusNumber)
+ {
+ GenericGetPciData = BusHandler->GetBusData;
+ BusHandler->GetBusData = HalpXboxGetPciData;
+ GenericSetPciData = BusHandler->SetBusData;
+ BusHandler->SetBusData = HalpXboxSetPciData;
+ }
+}
+
+/* EOF */
reactos/include/internal
diff -N port.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ port.h 13 Dec 2004 16:18:25 -0000 1.5.6.1
@@ -0,0 +1,151 @@
+#ifndef __INCLUDE_INTERNAL_PORT_H
+#define __INCLUDE_INTERNAL_PORT_H
+
+#include <napi/lpc.h>
+
+typedef
+struct _EPORT
+{
+ KSPIN_LOCK Lock;
+ KEVENT Event;
+
+ ULONG State;
+
+ struct _EPORT * OtherPort;
+
+ ULONG QueueLength;
+ LIST_ENTRY QueueListHead;
+
+ ULONG ConnectQueueLength;
+ LIST_ENTRY ConnectQueueListHead;
+
+ ULONG MaxDataLength;
+ ULONG MaxConnectInfoLength;
+
+} EPORT, * PEPORT;
+
+
+typedef struct _EPORT_TERMINATION_REQUEST
+{
+ LIST_ENTRY ThreadListEntry;
+ PEPORT Port;
+
+} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
+
+
+NTSTATUS
+STDCALL
+LpcRequestPort (
+ PEPORT Port,
+ PLPC_MESSAGE LpcMessage
+ );
+NTSTATUS
+STDCALL
+LpcSendTerminationPort (
+ PEPORT Port,
+ TIME CreationTime
+ );
+
+
+/* Port Object Access */
+
+#define PORT_ALL_ACCESS (0x1)
+
+
+/* EPORT.State */
+
+#define EPORT_INACTIVE (0)
+#define EPORT_WAIT_FOR_CONNECT (1)
+#define EPORT_WAIT_FOR_ACCEPT (2)
+#define EPORT_WAIT_FOR_COMPLETE_SRV (3)
+#define EPORT_WAIT_FOR_COMPLETE_CLT (4)
+#define EPORT_CONNECTED_CLIENT (5)
+#define EPORT_CONNECTED_SERVER (6)
+#define EPORT_DISCONNECTED (7)
+
+typedef
+struct _QUEUEDMESSAGE
+{
+ PEPORT Sender;
+ LIST_ENTRY QueueListEntry;
+ LPC_MESSAGE Message;
+ UCHAR MessageData [MAX_MESSAGE_DATA];
+
+} QUEUEDMESSAGE, *PQUEUEDMESSAGE;
+
+/* Code in ntoskrnl/lpc/close.c */
+
+VOID
+NiClosePort (
+ PVOID ObjectBody,
+ ULONG HandleCount
+ );
+VOID
+NiDeletePort (
+ IN PVOID ObjectBody
+ );
+
+
+/* Code in ntoskrnl/lpc/queue.c */
+
+VOID
+STDCALL
+EiEnqueueConnectMessagePort (
+ IN OUT PEPORT Port,
+ IN PQUEUEDMESSAGE Message
+ );
+VOID
+STDCALL
+EiEnqueueMessagePort (
+ IN OUT PEPORT Port,
+ IN PQUEUEDMESSAGE Message
+ );
+PQUEUEDMESSAGE
+STDCALL
+EiDequeueConnectMessagePort (
+ IN OUT PEPORT Port
+ );
+PQUEUEDMESSAGE
+STDCALL
+EiDequeueMessagePort (
+ IN OUT PEPORT Port
+ );
+
+/* Code in ntoskrnl/lpc/create.c */
+
+NTSTATUS
+NiCreatePort (
+ PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_ATTRIBUTES ObjectAttributes
+ );
+
+/* Code in ntoskrnl/lpc/port.c */
+
+NTSTATUS
+STDCALL
+NiInitializePort (
+ IN OUT PEPORT Port
+ );
+NTSTATUS
+NiInitPort (
+ VOID
+ );
+
+extern POBJECT_TYPE ExPortType;
+extern ULONG EiNextLpcMessageId;
+
+/* Code in ntoskrnl/lpc/reply.c */
+
+NTSTATUS
+STDCALL
+EiReplyOrRequestPort (
+ IN PEPORT Port,
+ IN PLPC_MESSAGE LpcReply,
+ IN ULONG MessageType,
+ IN PEPORT Sender
+ );
+
+
+#endif /* __INCLUDE_INTERNAL_PORT_H */
reactos/lib/advapi32/crypt
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:25 -0000 1.1.2.1
@@ -0,0 +1,2 @@
+*.o
+.*.d
reactos/lib/advapi32/crypt
diff -N crypt.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt.c 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,1926 @@
+/*
+ * Copyright 1999 Ian Schmidt
+ * Copyright 2001 Travis Michielsen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/***********************************************************************
+ *
+ * TODO:
+ * - Reference counting
+ * - Thread-safing
+ * - Signature checking
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+#define NDEBUG
+#include <debug.h>
+
+
+HWND crypt_hWindow = 0;
+
+#define CRYPT_ReturnLastError(err) {SetLastError(err); return FALSE;}
+
+#define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size))
+#define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer))
+
+static inline PSTR CRYPT_GetProvKeyName(PCSTR pProvName)
+{
+ PCSTR KEYSTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\";
+ PSTR keyname;
+
+ keyname = CRYPT_Alloc(strlen(KEYSTR) + strlen(pProvName) +1);
+ if (keyname)
+ {
+ strcpy(keyname, KEYSTR);
+ strcpy(keyname + strlen(KEYSTR), pProvName);
+ }
+ else
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ }
+
+ return keyname;
+}
+
+static inline PSTR CRYPT_GetTypeKeyName(DWORD dwType, BOOL user)
+{
+ PCSTR MACHINESTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider Types\\Type XXX";
+ PCSTR USERSTR = "Software\\Microsoft\\Cryptography\\Provider Type XXX";
+ PSTR keyname;
+ PSTR ptr;
+
+ keyname = CRYPT_Alloc( (user ? strlen(USERSTR) : strlen(MACHINESTR)) +1);
+ if (keyname)
+ {
+ user ? strcpy(keyname, USERSTR) : strcpy(keyname, MACHINESTR);
+ ptr = keyname + strlen(keyname);
+ *(--ptr) = (dwType % 10) + '0';
+ *(--ptr) = ((dwType / 10) % 10) + '0';
+ *(--ptr) = (dwType / 100) + '0';
+ }
+ else
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ return keyname;
+}
+
+/* CRYPT_UnicodeTOANSI
+ * wstr - unicode string
+ * str - pointer to ANSI string
+ * strsize - size of buffer pointed to by str or -1 if we have to do the allocation
+ *
+ * returns TRUE if unsuccessfull, FALSE otherwise.
+ * if wstr is NULL, returns TRUE and sets str to NULL! Value of str should be checked after call
+ */
+static inline BOOL CRYPT_UnicodeToANSI(LPCWSTR wstr, LPSTR* str, int strsize)
+{
+ int count;
+
+ if (!wstr)
+ {
+ *str = NULL;
+ return TRUE;
+ }
+ count = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
+ count = count < strsize ? count : strsize;
+ if (strsize == -1)
+ *str = CRYPT_Alloc(count * sizeof(CHAR));
+ if (*str)
+ {
+ WideCharToMultiByte(CP_ACP, 0, wstr, -1, *str, count, NULL, NULL);
+ return TRUE;
+ }
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+}
+
+/* CRYPT_ANSITOUnicode
+ * str - ANSI string
+ * wstr - pointer to unicode string
+ * wstrsize - size of buffer pointed to by wstr or -1 if we have to do the allocation
+ */
+static inline BOOL CRYPT_ANSIToUnicode(LPCSTR str, LPWSTR* wstr, int wstrsize)
+{
+ int wcount;
+
+ if (!str)
+ {
+ *wstr = NULL;
+ return TRUE;
+ }
+ wcount = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ wcount = wcount < wstrsize/sizeof(WCHAR) ? wcount : wstrsize/sizeof(WCHAR);
+ if (wstrsize == -1)
+ *wstr = CRYPT_Alloc(wcount * sizeof(WCHAR));
+ if (*wstr)
+ {
+ MultiByteToWideChar(CP_ACP, 0, str, -1, *wstr, wcount);
+ return TRUE;
+ }
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+}
+
+/* These next 2 functions are used by the VTableProvStruc structure */
+static BOOL CALLBACK CRYPT_VerifyImage(LPCSTR lpszImage, BYTE* pData)
+{
+ if (!lpszImage || !pData)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ DPRINT1("FIXME (%s, %p): not verifying image\n", lpszImage, pData);
+
+ return TRUE;
+}
+
+static BOOL CALLBACK CRYPT_ReturnhWnd(HWND *phWnd)
+{
+ if (!phWnd)
+ return FALSE;
+ *phWnd = crypt_hWindow;
+ return TRUE;
+}
+
+#define CRYPT_GetProvFunc(name) \
+ if ( !(provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)) ) goto error
+
+#define CRYPT_GetProvFuncOpt(name) \
+ provider->pFuncs->p##name = (void*)GetProcAddress(provider->hModule, #name)
+PCRYPTPROV CRYPT_LoadProvider(PSTR pImage)
+{
+ PCRYPTPROV provider;
+ DWORD errorcode = ERROR_NOT_ENOUGH_MEMORY;
+
+ if (!(provider = CRYPT_Alloc(sizeof(CRYPTPROV))))
+ goto error;
+ if (!(provider->pFuncs = CRYPT_Alloc(sizeof(PROVFUNCS))))
+ goto error;
+ if (!(provider->pVTable = CRYPT_Alloc(sizeof(VTableProvStruc))))
+ goto error;
+ if (!(provider->hModule = LoadLibraryA(pImage)))
+ {
+ errorcode = (GetLastError() == ERROR_FILE_NOT_FOUND) ? NTE_PROV_DLL_NOT_FOUND : NTE_PROVIDER_DLL_FAIL;
+ DPRINT1("Failed to load dll %s\n", pImage);
+ goto error;
+ }
+ provider->refcount = 1;
+
+ errorcode = NTE_PROVIDER_DLL_FAIL;
+ CRYPT_GetProvFunc(CPAcquireContext);
+ CRYPT_GetProvFunc(CPCreateHash);
+ CRYPT_GetProvFunc(CPDecrypt);
+ CRYPT_GetProvFunc(CPDeriveKey);
+ CRYPT_GetProvFunc(CPDestroyHash);
+ CRYPT_GetProvFunc(CPDestroyKey);
+ CRYPT_GetProvFuncOpt(CPDuplicateHash);
+ CRYPT_GetProvFuncOpt(CPDuplicateKey);
+ CRYPT_GetProvFunc(CPEncrypt);
+ CRYPT_GetProvFunc(CPExportKey);
+ CRYPT_GetProvFunc(CPGenKey);
+ CRYPT_GetProvFunc(CPGenRandom);
+ CRYPT_GetProvFunc(CPGetHashParam);
+ CRYPT_GetProvFunc(CPGetKeyParam);
+ CRYPT_GetProvFunc(CPGetProvParam);
+ CRYPT_GetProvFunc(CPGetUserKey);
+ CRYPT_GetProvFunc(CPHashData);
+ CRYPT_GetProvFunc(CPHashSessionKey);
+ CRYPT_GetProvFunc(CPImportKey);
+ CRYPT_GetProvFunc(CPReleaseContext);
+ CRYPT_GetProvFunc(CPSetHashParam);
+ CRYPT_GetProvFunc(CPSetKeyParam);
+ CRYPT_GetProvFunc(CPSetProvParam);
+ CRYPT_GetProvFunc(CPSignHash);
+ CRYPT_GetProvFunc(CPVerifySignature);
+
+ /* FIXME: Not sure what the pbContextInfo field is for.
+ * Does it need memory allocation?
+ */
+ provider->pVTable->Version = 3;
+ provider->pVTable->pFuncVerifyImage = (FARPROC)CRYPT_VerifyImage;
+ provider->pVTable->pFuncReturnhWnd = (FARPROC)CRYPT_ReturnhWnd;
+ provider->pVTable->dwProvType = 0;
+ provider->pVTable->pbContextInfo = NULL;
+ provider->pVTable->cbContextInfo = 0;
+ provider->pVTable->pszProvName = NULL;
+ return provider;
+
+error:
+ SetLastError(errorcode);
+ if (provider)
+ {
+ if (provider->hModule)
+ FreeLibrary(provider->hModule);
+ CRYPT_Free(provider->pVTable);
+ CRYPT_Free(provider->pFuncs);
+ CRYPT_Free(provider);
+ }
+ return NULL;
+}
+#undef CRYPT_GetProvFunc
+#undef CRYPT_GetProvFuncOpt
+
+
+/******************************************************************************
+ * CryptAcquireContextA (ADVAPI32.@)
+ * Acquire a crypto provider context handle.
+ *
+ * PARAMS
+ * phProv: Pointer to HCRYPTPROV for the output.
+ * pszContainer: Key Container Name
+ * pszProvider: Cryptographic Service Provider Name
+ * dwProvType: Crypto provider type to get a handle.
+ * dwFlags: flags for the operation
+ *
+ * RETURNS TRUE on success, FALSE on failure.
+ */
+BOOL WINAPI CryptAcquireContextA (HCRYPTPROV *phProv, LPCSTR pszContainer,
+ LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
+{
+ PCRYPTPROV pProv = NULL;
+ HKEY key;
+ PSTR imagepath = NULL, keyname = NULL, provname = NULL, temp = NULL;
+ BYTE* signature;
+ DWORD keytype, type, len;
+ ULONG r;
+
+ DPRINT("(%p, %s, %s, %ld, %08lx)\n", phProv, pszContainer,
+ pszProvider, dwProvType, dwFlags);
+
+ if (dwProvType < 1 || dwProvType > MAXPROVTYPES)
+ {
+ SetLastError(NTE_BAD_PROV_TYPE);
+ return FALSE;
+ }
+
+ if (!phProv)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!pszProvider || !*pszProvider)
+ {
+ /* No CSP name specified so try the user default CSP first
+ * then try the machine default CSP
+ */
+ if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, TRUE)))
+ {
+ DPRINT("No provider registered for crypto provider type %ld.\n", dwProvType);
+ SetLastError(NTE_PROV_TYPE_NOT_DEF);
+ return FALSE;
+ }
+
+ if (RegOpenKeyA(HKEY_CURRENT_USER, keyname, &key))
+ {
+ CRYPT_Free(keyname);
+ if (!(keyname = CRYPT_GetTypeKeyName(dwProvType, FALSE)))
+ {
+ DPRINT("No type registered for crypto provider type %ld.\n", dwProvType);
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_NOT_DEF);
+ goto error;
+ }
+
+ if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key))
+ {
+ DPRINT("Did not find registry entry of crypto provider for %S.\n", keyname);
+ CRYPT_Free(keyname);
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_NOT_DEF);
+ goto error;
+ }
+ }
+
+ CRYPT_Free(keyname);
+ r = RegQueryValueExA(key, "Name", NULL, &keytype, NULL, &len);
+ if (r != ERROR_SUCCESS || !len || keytype != REG_SZ)
+ {
+ DPRINT("error %ld reading size of 'Name' from registry\n", r );
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+ if (!(provname = CRYPT_Alloc(len)))
+ {
+ RegCloseKey(key);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto error;
+ }
+ r = RegQueryValueExA(key, "Name", NULL, NULL, provname, &len);
+ if (r != ERROR_SUCCESS)
+ {
+ DPRINT("error %ld reading 'Name' from registry\n", r );
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+ RegCloseKey(key);
+ }
+ else
+ {
+ if (!(provname = CRYPT_Alloc(strlen(pszProvider) +1)))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto error;
+ }
+ strcpy(provname, pszProvider);
+ }
+
+ keyname = CRYPT_GetProvKeyName(provname);
+ r = RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &key);
+ CRYPT_Free(keyname);
+ if (r != ERROR_SUCCESS)
+ {
+ SetLastError(NTE_KEYSET_NOT_DEF);
+ goto error;
+ }
+ len = sizeof(DWORD);
+ r = RegQueryValueExA(key, "Type", NULL, NULL, (BYTE*)&type, &len);
+ if (r != ERROR_SUCCESS)
+ {
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+ if (type != dwProvType)
+ {
+ DPRINT("Crypto provider has wrong type (%ld vs expected %ld).\n", type, dwProvType);
+ SetLastError(NTE_PROV_TYPE_NO_MATCH);
+ goto error;
+ }
+
+ r = RegQueryValueExA(key, "Image Path", NULL, &keytype, NULL, &len);
+ if ( r != ERROR_SUCCESS || keytype != REG_SZ)
+ {
+ DPRINT("error %ld reading size of 'Image Path' from registry\n", r );
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+ if (!(temp = CRYPT_Alloc(len)))
+ {
+ RegCloseKey(key);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto error;
+ }
+ r = RegQueryValueExA(key, "Image Path", NULL, NULL, temp, &len);
+ if (r != ERROR_SUCCESS)
+ {
+ DPRINT("error %ld reading 'Image Path' from registry\n", r );
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+
+ r = RegQueryValueExA(key, "Signature", NULL, &keytype, NULL, &len);
+ if (r == ERROR_SUCCESS && keytype == REG_BINARY)
+ {
+ if (!(signature = CRYPT_Alloc(len)))
+ {
+ RegCloseKey(key);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto error;
+ }
+ r = RegQueryValueExA(key, "Signature", NULL, NULL, signature, &len);
+ if (r != ERROR_SUCCESS)
+ {
+ DPRINT("error %ld reading 'Signature'\n", r );
+ CRYPT_Free(signature);
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+ }
+ else
+ {
+ r = RegQueryValueExA(key, "SigInFile", NULL, &keytype, NULL, &len);
+ if (r != ERROR_SUCCESS)
+ {
+ DPRINT("error %ld reading size of 'SigInFile'\n", r );
+ RegCloseKey(key);
+ SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+ goto error;
+ }
+ else
+ {
+ /* FIXME: The presence of the SigInFile value indicates the
+ * provider's signature is in its resources, so need to read it.
+ * But since CRYPT_VerifyImage is stubbed, provide any old thing
+ * for now.
+ */
+ if (!(signature = CRYPT_Alloc(1)))
+ {
+ RegCloseKey(key);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto error;
+ }
+ }
+ }
+ RegCloseKey(key);
+ len = ExpandEnvironmentStringsA(temp, NULL, 0);
+ if (!(imagepath = CRYPT_Alloc(len)))
+ {
+ CRYPT_Free(signature);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto error;
+ }
+ if (!ExpandEnvironmentStringsA(temp, imagepath, len))
+ {
+ CRYPT_Free(signature);
+ /* ExpandEnvironmentStrings will call SetLastError */
+ goto error;
+ }
+
+ if (!CRYPT_VerifyImage(imagepath, signature))
+ {
+ CRYPT_Free(signature);
+ SetLastError(NTE_SIGNATURE_FILE_BAD);
+ goto error;
+ }
+ pProv = CRYPT_LoadProvider(imagepath);
+ CRYPT_Free(signature);
+ if (!pProv)
+ {
+ /* CRYPT_LoadProvider calls SetLastError */
+ goto error;
+ }
+ pProv->pVTable->dwProvType = dwProvType;
+ pProv->pVTable->pszProvName = provname;
+ if (pProv->pFuncs->pCPAcquireContext(&pProv->hPrivate, (CHAR*)pszContainer, dwFlags, pProv->pVTable))
+ {
+ /* MSDN: When this flag is set, the value returned in phProv is undefined,
+ * and thus, the CryptReleaseContext function need not be called afterwards.
+ * Therefore, we must clean up everything now.
+ */
+ if (dwFlags & CRYPT_DELETEKEYSET)
+ {
+ FreeLibrary(pProv->hModule);
+ CRYPT_Free(provname);
+ CRYPT_Free(pProv->pFuncs);
+ CRYPT_Free(pProv);
+ }
+ else
+ {
+ *phProv = (HCRYPTPROV)pProv;
+ }
+ CRYPT_Free(temp);
+ CRYPT_Free(imagepath);
+ return TRUE;
+ }
+ /* FALLTHROUGH TO ERROR IF FALSE - CSP internal error! */
+error:
+ if (pProv)
+ {
+ if (pProv->hModule)
+ FreeLibrary(pProv->hModule);
+ if (pProv->pVTable)
+ CRYPT_Free(pProv->pVTable);
+ if (pProv->pFuncs)
+ CRYPT_Free(pProv->pFuncs);
+ CRYPT_Free(pProv);
+ }
+ if (provname)
+ CRYPT_Free(provname);
+ if (temp)
+ CRYPT_Free(temp);
+ if (imagepath)
+ CRYPT_Free(imagepath);
+ return FALSE;
+}
+
+/******************************************************************************
+ * CryptAcquireContextW (ADVAPI32.@)
+ *
+ * see CryptAcquireContextA
+ */
+BOOL WINAPI CryptAcquireContextW (HCRYPTPROV *phProv, LPCWSTR pszContainer,
+ LPCWSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
+{
+ PSTR pProvider = NULL, pContainer = NULL;
+ BOOL ret = FALSE;
+
+ DPRINT("(%p, %S, %S, %ld, %08lx)\n", phProv, pszContainer,
+ pszProvider, dwProvType, dwFlags);
+
+ if (!CRYPT_UnicodeToANSI(pszContainer, &pContainer, -1))
+ CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+ if (!CRYPT_UnicodeToANSI(pszProvider, &pProvider, -1))
+ {
+ CRYPT_Free(pContainer);
+ CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+ }
+
+ ret = CryptAcquireContextA(phProv, pContainer, pProvider, dwProvType, dwFlags);
+
+ if (pContainer)
+ CRYPT_Free(pContainer);
+ if (pProvider)
+ CRYPT_Free(pProvider);
+
+ return ret;
+}
+
+/******************************************************************************
+ * CryptContextAddRef (ADVAPI32.@)
+ *
+ * Increases reference count of a cryptographic service provider handle
+ * by one.
+ *
+ * PARAMS
+ * hProv [I] Handle to the CSP whose reference is being incremented.
+ * pdwReserved [IN] Reserved for future use and must be NULL.
+ * dwFlags [I] Reserved for future use and must be NULL.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptContextAddRef (HCRYPTPROV hProv, DWORD *pdwReserved, DWORD dwFlags)
+{
+ PCRYPTPROV pProv = (PCRYPTPROV)hProv;
+
+ DPRINT("(0x%lx, %p, %08lx)\n", hProv, pdwReserved, dwFlags);
+
+ if (!pProv)
+ {
+ SetLastError(NTE_BAD_UID);
+ return FALSE;
+ }
+
+ pProv->refcount++;
+ return TRUE;
+}
+
+/******************************************************************************
+ * CryptReleaseContext (ADVAPI32.@)
+ *
+ * Releases the handle of a CSP. Reference count is decreased.
+ *
+ * PARAMS
+ * hProv [I] Handle of a CSP.
+ * dwFlags [I] Reserved for future use and must be NULL.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, DWORD dwFlags)
+{
+ PCRYPTPROV pProv = (PCRYPTPROV)hProv;
+ BOOL ret = TRUE;
+
+ DPRINT("(0x%lx, %08ld)\n", hProv, dwFlags);
+
+ if (!pProv)
+ {
+ SetLastError(NTE_BAD_UID);
+ return FALSE;
+ }
+
+ pProv->refcount--;
+ if (pProv->refcount <= 0)
+ {
+ ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
+ FreeLibrary(pProv->hModule);
+#if 0
+ CRYPT_Free(pProv->pVTable->pContextInfo);
+#endif
+ CRYPT_Free(pProv->pVTable->pszProvName);
+ CRYPT_Free(pProv->pVTable);
+ CRYPT_Free(pProv->pFuncs);
+ CRYPT_Free(pProv);
+ }
+ return ret;
+}
+
+/******************************************************************************
+ * CryptGenRandom (ADVAPI32.@)
+ *
+ * Fills a buffer with cryptographically random bytes.
+ *
+ * PARAMS
+ * hProv [I] Handle of a CSP.
+ * dwLen [I] Number of bytes to generate.
+ * pbBuffer [I/O] Buffer to contain random bytes.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ * NOTES
+ * pdBuffer must be at least dwLen bytes long.
+ */
+BOOL WINAPI CryptGenRandom (HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer)
+{
+ PCRYPTPROV prov = (PCRYPTPROV)hProv;
+
+ DPRINT("(0x%lx, %ld, %p)\n", hProv, dwLen, pbBuffer);
+
+ if (!hProv)
+ CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+
+ return prov->pFuncs->pCPGenRandom(prov->hPrivate, dwLen, pbBuffer);
+}
+
+/******************************************************************************
+ * CryptCreateHash (ADVAPI32.@)
+ *
+ * Initiates the hashing of a stream of data.
+ *
+ * PARAMS
+ * hProv [I] Handle of a CSP.
+ * Algid [I] Identifies the hash algorithm to use.
+ * hKey [I] Key for the hash (if required).
+ * dwFlags [I] Reserved for future use and must be NULL.
+ * phHash [O] Address of the future handle to the new hash object.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ * NOTES
+ * If the algorithm is a keyed hash, hKey is the key.
+ */
+BOOL WINAPI CryptCreateHash (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey,
+ DWORD dwFlags, HCRYPTHASH *phHash)
+{
+ PCRYPTPROV prov = (PCRYPTPROV)hProv;
+ PCRYPTKEY key = (PCRYPTKEY)hKey;
+ PCRYPTHASH hash;
+
+ DPRINT("(0x%lx, 0x%x, 0x%lx, %08lx, %p)\n", hProv, Algid, hKey, dwFlags, phHash);
+
+ if (!prov)
+ CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+ if (!phHash)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+ if (dwFlags)
+ CRYPT_ReturnLastError(NTE_BAD_FLAGS);
+ if (!(hash = CRYPT_Alloc(sizeof(CRYPTHASH))))
+ CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+ hash->pProvider = prov;
+
+ if (prov->pFuncs->pCPCreateHash(prov->hPrivate, Algid,
+ key ? key->hPrivate : 0, 0, &hash->hPrivate))
+ {
+ *phHash = (HCRYPTHASH)hash;
+ return TRUE;
+ }
+
+ /* CSP error! */
+ CRYPT_Free(hash);
+ *phHash = 0;
+ return FALSE;
+}
+
+/******************************************************************************
+ * CryptDecrypt (ADVAPI32.@)
+ *
+ * Decrypts data encrypted by CryptEncrypt.
+ *
+ * PARAMS
+ * hKey [I] Handle to the decryption key.
+ * hHash [I] Handle to a hash object.
+ * Final [I] TRUE if this is the last section to be decrypted.
+ * dwFlags [I] Reserved for future use. Can be CRYPT_OAEP.
+ * pbData [I/O] Buffer that holds the encrypted data. Holds decrypted
+ * data on return
+ * pdwDataLen [I/O] Length of pbData before and after the call.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptDecrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
+ DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen)
+{
+ PCRYPTPROV prov;
+ PCRYPTKEY key = (PCRYPTKEY)hKey;
+ PCRYPTHASH hash = (PCRYPTHASH)hHash;
+
+ DPRINT("(0x%lx, 0x%lx, %d, %08lx, %p, %p)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen);
+
+ if (!key || !pbData || !pdwDataLen)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+ prov = key->pProvider;
+ return prov->pFuncs->pCPDecrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
+ Final, dwFlags, pbData, pdwDataLen);
+}
+
+/******************************************************************************
+ * CryptDeriveKey (ADVAPI32.@)
+ *
+ * Generates session keys derived from a base data value.
+ *
+ * PARAMS
+ * hProv [I] Handle to a CSP.
+ * Algid [I] Identifies the symmetric encryption algorithm to use.
+ * hBaseData [I] Handle to a hash object.
+ * dwFlags [I] Type of key to generate.
+ * phKey [I/O] Address of the newly generated key.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptDeriveKey (HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData,
+ DWORD dwFlags, HCRYPTKEY *phKey)
+{
+ PCRYPTPROV prov = (PCRYPTPROV)hProv;
+ PCRYPTHASH hash = (PCRYPTHASH)hBaseData;
+ PCRYPTKEY key;
+
+ DPRINT("(0x%lx, 0x%08x, 0x%lx, 0x%08lx, %p)\n", hProv, Algid, hBaseData, dwFlags, phKey);
+
+ if (!prov || !hash)
+ CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+ if (!phKey)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+ if (!(key = CRYPT_Alloc(sizeof(CRYPTKEY))))
+ CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+ key->pProvider = prov;
+ if (prov->pFuncs->pCPDeriveKey(prov->hPrivate, Algid, hash->hPrivate, dwFlags, &key->hPrivate))
+ {
+ *phKey = (HCRYPTKEY)key;
+ return TRUE;
+ }
+
+ /* CSP error! */
+ CRYPT_Free(key);
+ *phKey = 0;
+ return FALSE;
+}
+
+/******************************************************************************
+ * CryptDestroyHash (ADVAPI32.@)
+ *
+ * Destroys the hash object referenced by hHash.
+ *
+ * PARAMS
+ * hHash [I] Handle of the hash object to be destroyed.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptDestroyHash (HCRYPTHASH hHash)
+{
+ PCRYPTHASH hash = (PCRYPTHASH)hHash;
+ PCRYPTPROV prov;
+ BOOL ret;
+
+ DPRINT("(0x%lx)\n", hHash);
+
+ if (!hash)
+ CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+
+ prov = hash->pProvider;
+ ret = prov->pFuncs->pCPDestroyHash(prov->hPrivate, hash->hPrivate);
+ CRYPT_Free(hash);
+ return ret;
+}
+
+/******************************************************************************
+ * CryptDestroyKey (ADVAPI32.@)
+ *
+ * Releases the handle referenced by hKey.
+ *
+ * PARAMS
+ * hKey [I] Handle of the key to be destroyed.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptDestroyKey (HCRYPTKEY hKey)
+{
+ PCRYPTKEY key = (PCRYPTKEY)hKey;
+ PCRYPTPROV prov;
+ BOOL ret;
+
+ DPRINT("(0x%lx)\n", hKey);
+
+ if (!key)
+ CRYPT_ReturnLastError(ERROR_INVALID_HANDLE);
+
+ prov = key->pProvider;
+ ret = prov->pFuncs->pCPDestroyKey(prov->hPrivate, key->hPrivate);
+ CRYPT_Free(key);
+ return ret;
+}
+
+/******************************************************************************
+ * CryptDuplicateHash (ADVAPI32.@)
+ *
+ * Duplicates a hash.
+ *
+ * PARAMS
+ * hHash [I] Handle to the hash to be copied.
+ * pdwReserved [I] Reserved for future use and must be zero.
+ * dwFlags [I] Reserved for future use and must be zero.
+ * phHash [O] Address of the handle to receive the copy.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptDuplicateHash (HCRYPTHASH hHash, DWORD *pdwReserved,
+ DWORD dwFlags, HCRYPTHASH *phHash)
+{
+ PCRYPTPROV prov;
+ PCRYPTHASH orghash, newhash;
+
+ DPRINT("(0x%lx, %p, %08ld, %p)\n", hHash, pdwReserved, dwFlags, phHash);
+
+ orghash = (PCRYPTHASH)hHash;
+ if (!orghash || pdwReserved || !phHash)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+ prov = orghash->pProvider;
+ if (!prov->pFuncs->pCPDuplicateHash)
+ CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+ if (!(newhash = CRYPT_Alloc(sizeof(CRYPTHASH))))
+ CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+ newhash->pProvider = prov;
+ if (prov->pFuncs->pCPDuplicateHash(prov->hPrivate, orghash->hPrivate, pdwReserved, dwFlags, &newhash->hPrivate))
+ {
+ *phHash = (HCRYPTHASH)newhash;
+ return TRUE;
+ }
+ CRYPT_Free(newhash);
+ return FALSE;
+}
+
+/******************************************************************************
+ * CryptDuplicateKey (ADVAPI32.@)
+ *
+ * Duplicate a key and the key's state.
+ *
+ * PARAMS
+ * hKey [I] Handle of the key to copy.
+ * pdwReserved [I] Reserved for future use and must be NULL.
+ * dwFlags [I] Reserved for future use and must be zero.
+ * phKey [I] Address of the handle to the duplicated key.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ */
+BOOL WINAPI CryptDuplicateKey (HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey)
+{
+ PCRYPTPROV prov;
+ PCRYPTKEY orgkey, newkey;
+
+ DPRINT("(0x%lx, %p, %08ld, %p)\n", hKey, pdwReserved, dwFlags, phKey);
+
+ orgkey = (PCRYPTKEY)hKey;
+ if (!orgkey || pdwReserved || !phKey)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+ prov = orgkey->pProvider;
+ if (!prov->pFuncs->pCPDuplicateKey)
+ CRYPT_ReturnLastError(ERROR_CALL_NOT_IMPLEMENTED);
+
+ if (!(newkey = CRYPT_Alloc(sizeof(CRYPTKEY))))
+ CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+ newkey->pProvider = prov;
+ if (prov->pFuncs->pCPDuplicateKey(prov->hPrivate, orgkey->hPrivate, pdwReserved, dwFlags, &newkey->hPrivate))
+ {
+ *phKey = (HCRYPTKEY)newkey;
+ return TRUE;
+ }
+ CRYPT_Free(newkey);
+ return FALSE;
+}
+
+/******************************************************************************
+ * CryptEncrypt (ADVAPI32.@)
+ *
+ * Encrypts data.
+ *
+ * PARAMS
+ * hKey [I] Handle to the enryption key.
+ * hHash [I] Handle to a hash object.
+ * Final [I] TRUE if this is the last section to encrypt.
+ * dwFlags [I] Can be CRYPT_OAEP.
+ * pbData [I/O] Data to be encrypted. Contains encrypted data after call.
+ * pdwDataLen [I/O] Length of the data to encrypt. Contains the length of the
+ * encrypted data after call.
+ * dwBufLen [I] Length of the input pbData buffer.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ * NOTES
+ * If pbData is NULL, CryptEncrypt determines stores the number of bytes
+ * required for the returned data in pdwDataLen.
+ */
+BOOL WINAPI CryptEncrypt (HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final,
+ DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen)
+{
+ PCRYPTPROV prov;
+ PCRYPTKEY key = (PCRYPTKEY)hKey;
+ PCRYPTHASH hash = (PCRYPTHASH)hHash;
+
+ DPRINT("(0x%lx, 0x%lx, %d, %08ld, %p, %p, %ld)\n", hKey, hHash, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
+
+ if (!key || !pdwDataLen)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+
+ prov = key->pProvider;
+ return prov->pFuncs->pCPEncrypt(prov->hPrivate, key->hPrivate, hash ? hash->hPrivate : 0,
+ Final, dwFlags, pbData, pdwDataLen, dwBufLen);
+}
+
+/******************************************************************************
+ * CryptEnumProvidersW (ADVAPI32.@)
+ *
+ * Returns the next availabe CSP.
+ *
+ * PARAMS
+ * dwIndex [I] Index of the next provider to be enumerated.
+ * pdwReserved [I] Reserved for future use and must be NULL.
+ * dwFlags [I] Reserved for future use and must be zero.
+ * pdwProvType [O] DWORD designating the type of the provider.
+ * pszProvName [O] Buffer that receives data from the provider.
+ * pcbProvName [I/O] Specifies the size of pszProvName. Contains the number
+ * of bytes stored in the buffer on return.
+ *
+ * RETURNS
+ * Success: TRUE
+ * Failure: FALSE
+ *
+ * NOTES
+ * If pszProvName is NULL, CryptEnumProvidersW sets the size of the name
+ * for memory allocation purposes.
+ */
+BOOL WINAPI CryptEnumProvidersW (DWORD dwIndex, DWORD *pdwReserved,
+ DWORD dwFlags, DWORD *pdwProvType, LPWSTR pszProvName, DWORD *pcbProvName)
+{
+ HKEY hKey;
+
+ DPRINT("(%ld, %p, %ld, %p, %p, %p)\n", dwIndex, pdwReserved, dwFlags,
+ pdwProvType, pszProvName, pcbProvName);
+
+ if (pdwReserved || !pcbProvName)
+ CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
+ if (dwFlags)
+ CRYPT_ReturnLastError(NTE_BAD_FLAGS);
+
+ if (RegOpenKeyW(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Cryptography\\Defaults\\Provider",
[truncated at 1000 lines; 930 more skipped]
reactos/lib/advapi32/crypt
diff -N crypt.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt.h 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,86 @@
+/*
+ * Driver routines
+ *
+ * Copyright 2001 - Travis Michielsen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_CRYPT_H
+#define __WINE_CRYPT_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wincrypt.h"
+
+typedef struct tagPROVFUNCS
+{
+ BOOL (WINAPI *pCPAcquireContext)(HCRYPTPROV *phProv, LPSTR pszContainer, DWORD dwFlags, PVTableProvStruc pVTable);
+ BOOL (WINAPI *pCPCreateHash)(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash);
+ BOOL (WINAPI *pCPDecrypt)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen);
+ BOOL (WINAPI *pCPDeriveKey)(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey);
+ BOOL (WINAPI *pCPDestroyHash)(HCRYPTPROV hProv, HCRYPTHASH hHash);
+ BOOL (WINAPI *pCPDestroyKey)(HCRYPTPROV hProv, HCRYPTKEY hKey);
+ BOOL (WINAPI *pCPDuplicateHash)(HCRYPTPROV hUID, HCRYPTHASH hHash, DWORD *pdwReserved, DWORD dwFlags, HCRYPTHASH *phHash);
+ BOOL (WINAPI *pCPDuplicateKey)(HCRYPTPROV hUID, HCRYPTKEY hKey, DWORD *pdwReserved, DWORD dwFlags, HCRYPTKEY *phKey);
+ BOOL (WINAPI *pCPEncrypt)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen, DWORD dwBufLen);
+ BOOL (WINAPI *pCPExportKey)(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubKey, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen);
+ BOOL (WINAPI *pCPGenKey)(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags, HCRYPTKEY *phKey);
+ BOOL (WINAPI *pCPGenRandom)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);
+ BOOL (WINAPI *pCPGetHashParam)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags);
+ BOOL (WINAPI *pCPGetKeyParam)(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags);
+ BOOL (WINAPI *pCPGetProvParam)(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags);
+ BOOL (WINAPI *pCPGetUserKey)(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey);
+ BOOL (WINAPI *pCPHashData)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags);
+ BOOL (WINAPI *pCPHashSessionKey)(HCRYPTPROV hProv, HCRYPTHASH hHash, HCRYPTKEY hKey, DWORD dwFlags);
+ BOOL (WINAPI *pCPImportKey)(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey);
+ BOOL (WINAPI *pCPReleaseContext)(HCRYPTPROV hProv, DWORD dwFlags);
+ BOOL (WINAPI *pCPSetHashParam)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
+ BOOL (WINAPI *pCPSetKeyParam)(HCRYPTPROV hProv, HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
+ BOOL (WINAPI *pCPSetProvParam)(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags);
+ BOOL (WINAPI *pCPSignHash)(HCRYPTPROV hProv, HCRYPTHASH hHash, DWORD dwKeySpec, LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature, DWORD *pdwSigLen);
+ BOOL (WINAPI *pCPVerifySignature)(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature, DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription, DWORD dwFlags);
+} PROVFUNCS, *PPROVFUNCS;
+
+typedef struct tagCRYPTPROV
+{
+ UINT refcount;
+ HMODULE hModule;
+ PPROVFUNCS pFuncs;
+ HCRYPTPROV hPrivate; /*CSP's handle - Should not be given to application under any circumstances!*/
+ PVTableProvStruc pVTable;
+} CRYPTPROV, *PCRYPTPROV;
+
+typedef struct tagCRYPTKEY
+{
+ PCRYPTPROV pProvider;
+ HCRYPTKEY hPrivate; /*CSP's handle - Should not be given to application under any circumstances!*/
+} CRYPTKEY, *PCRYPTKEY;
+
+typedef struct tagCRYPTHASH
+{
+ PCRYPTPROV pProvider;
+ HCRYPTHASH hPrivate; /*CSP's handle - Should not be given to application under any circumstances!*/
+} CRYPTHASH, *PCRYPTHASH;
+
+#define MAXPROVTYPES 999
+
+extern unsigned char *CRYPT_DESkey8to7( unsigned char *dst, const unsigned char *key );
+extern unsigned char *CRYPT_DEShash( unsigned char *dst, const unsigned char *key,
+ const unsigned char *src );
+
+#endif /* __WINE_CRYPT_H_ */
reactos/lib/advapi32/crypt
diff -N crypt_des.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt_des.c 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2004 Hans Leidekker
+ *
+ * Based on DES.c from libcifs
+ *
+ * Copyright (C) 2003, 2004 by Christopher R. Hertel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+static const unsigned char InitialPermuteMap[64] =
+{
+ 57, 49, 41, 33, 25, 17, 9, 1,
+ 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5,
+ 63, 55, 47, 39, 31, 23, 15, 7,
+ 56, 48, 40, 32, 24, 16, 8, 0,
+ 58, 50, 42, 34, 26, 18, 10, 2,
+ 60, 52, 44, 36, 28, 20, 12, 4,
+ 62, 54, 46, 38, 30, 22, 14, 6
+ };
+
+static const unsigned char KeyPermuteMap[56] =
+{
+ 49, 42, 35, 28, 21, 14, 7, 0,
+ 50, 43, 36, 29, 22, 15, 8, 1,
+ 51, 44, 37, 30, 23, 16, 9, 2,
+ 52, 45, 38, 31, 55, 48, 41, 34,
+ 27, 20, 13, 6, 54, 47, 40, 33,
+ 26, 19, 12, 5, 53, 46, 39, 32,
+ 25, 18, 11, 4, 24, 17, 10, 3,
+};
+
+static const unsigned char KeyRotation[16] =
+ { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
+
+static const unsigned char KeyCompression[48] =
+{
+ 13, 16, 10, 23, 0, 4, 2, 27,
+ 14, 5, 20, 9, 22, 18, 11, 3,
+ 25, 7, 15, 6, 26, 19, 12, 1,
+ 40, 51, 30, 36, 46, 54, 29, 39,
+ 50, 44, 32, 47, 43, 48, 38, 55,
+ 33, 52, 45, 41, 49, 35, 28, 31
+};
+
+static const unsigned char DataExpansion[48] =
+{
+ 31, 0, 1, 2, 3, 4, 3, 4,
+ 5, 6, 7, 8, 7, 8, 9, 10,
+ 11, 12, 11, 12, 13, 14, 15, 16,
+ 15, 16, 17, 18, 19, 20, 19, 20,
+ 21, 22, 23, 24, 23, 24, 25, 26,
+ 27, 28, 27, 28, 29, 30, 31, 0
+};
+
+static const unsigned char SBox[8][64] =
+{
+ { /* S0 */
+ 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
+ 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
+ 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
+ 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
+ },
+ { /* S1 */
+ 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
+ 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
+ 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
+ 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
+ },
+ { /* S2 */
+ 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
+ 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
+ 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
+ 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
+ },
+ { /* S3 */
+ 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
+ 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
+ 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
+ 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
+ },
+ { /* S4 */
+ 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
+ 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
+ 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
+ 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
+ },
+ { /* S5 */
+ 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
+ 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
+ 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
+ 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
+ },
+ { /* S6 */
+ 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
+ 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
+ 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
+ 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
+ },
+ { /* S7 */
+ 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
+ 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
+ 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
+ 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
+ }
+};
+
+static const unsigned char PBox[32] =
+{
+ 15, 6, 19, 20, 28, 11, 27, 16,
+ 0, 14, 22, 25, 4, 17, 30, 9,
+ 1, 7, 23, 13, 31, 26, 2, 8,
+ 18, 12, 29, 5, 21, 10, 3, 24
+};
+
+static const unsigned char FinalPermuteMap[64] =
+{
+ 7, 39, 15, 47, 23, 55, 31, 63,
+ 6, 38, 14, 46, 22, 54, 30, 62,
+ 5, 37, 13, 45, 21, 53, 29, 61,
+ 4, 36, 12, 44, 20, 52, 28, 60,
+ 3, 35, 11, 43, 19, 51, 27, 59,
+ 2, 34, 10, 42, 18, 50, 26, 58,
+ 1, 33, 9, 41, 17, 49, 25, 57,
+ 0, 32, 8, 40, 16, 48, 24, 56
+};
+
+#define CLRBIT(STR, IDX) ((STR)[(IDX)/8] &= ~(0x01 << (7 - ((IDX)%8))))
+#define SETBIT(STR, IDX) ((STR)[(IDX)/8] |= (0x01 << (7 - ((IDX)%8))))
+#define GETBIT(STR, IDX) ((((STR)[(IDX)/8]) >> (7 - ((IDX)%8))) & 0x01)
+
+static void Permute(unsigned char *dst, const unsigned char *src, const unsigned char *map, const int mapsize)
+{
+ int bitcount, i;
+
+ for (i = 0; i < mapsize; i++)
+ dst[i] = 0;
+
+ bitcount = mapsize * 8;
+
+ for (i = 0; i < bitcount; i++)
+ {
+ if (GETBIT(src, map[i]))
+ SETBIT(dst, i);
+ }
+}
+
+static void KeyShift(unsigned char *key, const int numbits)
+{
+ int i;
+ unsigned char keep = key[0];
+
+ for (i = 0; i < numbits; i++)
+ {
+ int j;
+
+ for (j = 0; j < 7; j++)
+ {
+ if (j && (key[j] & 0x80))
+ key[j-1] |= 0x01;
+ key[j] <<= 1;
+ }
+
+ if (GETBIT(key, 27))
+ {
+ CLRBIT(key, 27);
+ SETBIT(key, 55);
+ }
+
+ if (keep & 0x80)
+ SETBIT(key, 27);
+
+ keep <<= 1;
+ }
+}
+
+static void sbox(unsigned char *dst, const unsigned char *src)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ dst[i] = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ int j, Snum, bitnum;
+
+ for (Snum = j = 0, bitnum = (i * 6); j < 6; j++, bitnum++)
+ {
+ Snum <<= 1;
+ Snum |= GETBIT(src, bitnum);
+ }
+
+ if (0 == (i%2))
+ dst[i/2] |= ((SBox[i][Snum]) << 4);
+ else
+ dst[i/2] |= SBox[i][Snum];
+ }
+}
+
+static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ dst[i] = a[i] ^ b[i];
+}
+
+unsigned char *CRYPT_DESkey8to7(unsigned char *dst, const unsigned char *key)
+{
+ int i;
+ unsigned char tmp[7];
+ static const unsigned char map8to7[56] =
+ {
+ 0, 1, 2, 3, 4, 5, 6,
+ 8, 9, 10, 11, 12, 13, 14,
+ 16, 17, 18, 19, 20, 21, 22,
+ 24, 25, 26, 27, 28, 29, 30,
+ 32, 33, 34, 35, 36, 37, 38,
+ 40, 41, 42, 43, 44, 45, 46,
+ 48, 49, 50, 51, 52, 53, 54,
+ 56, 57, 58, 59, 60, 61, 62
+ };
+
+ if ((dst == NULL) || (key == NULL))
+ return NULL;
+
+ Permute(tmp, key, map8to7, 7);
+
+ for (i = 0; i < 7; i++)
+ dst[i] = tmp[i];
+
+ return dst;
+}
+
+
+unsigned char *CRYPT_DEShash(unsigned char *dst, const unsigned char *key, const unsigned char *src)
+{
+ int i;
+ unsigned char K[7];
+ unsigned char D[8];
+
+ Permute(K, key, KeyPermuteMap, 7);
+ Permute(D, src, InitialPermuteMap, 8);
+
+ for (i = 0; i < 16; i++)
+ {
+ int j;
+ unsigned char *L = D;
+ unsigned char *R = &(D[4]);
+ unsigned char Rexp[6];
+ unsigned char Rn[4];
+ unsigned char SubK[6];
+
+ KeyShift(K, KeyRotation[i]);
+ Permute(SubK, K, KeyCompression, 6);
+
+ Permute(Rexp, R, DataExpansion, 6);
+ xor(Rexp, Rexp, SubK, 6);
+
+ sbox(Rn, Rexp);
+ Permute(Rexp, Rn, PBox, 4);
+ xor(Rn, L, Rexp, 4);
+
+ for (j = 0; j < 4; j++)
+ {
+ L[j] = R[j];
+ R[j] = Rn[j];
+ }
+ }
+
+ Permute(dst, D, FinalPermuteMap, 8);
+
+ return dst;
+}
reactos/lib/advapi32/crypt
diff -N crypt_lmhash.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt_lmhash.c 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2004 Hans Leidekker
+ *
+ * Based on LMHash.c from libcifs
+ *
+ * Copyright (C) 2004 by Christopher R. Hertel
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+
+static const unsigned char CRYPT_LMhash_Magic[8] =
+ { 'K', 'G', 'S', '!', '@', '#', '$', '%' };
+
+static void CRYPT_LMhash(unsigned char *dst, const unsigned char *pwd, const int len)
+{
+ int i, max = 14;
+ unsigned char tmp_pwd[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+
+ max = len > max ? max : len;
+
+ for (i = 0; i < max; i++)
+ tmp_pwd[i] = pwd[i];
+
+ CRYPT_DEShash(dst, tmp_pwd, CRYPT_LMhash_Magic);
+ CRYPT_DEShash(&dst[8], &tmp_pwd[7], CRYPT_LMhash_Magic);
+}
+
+NTSTATUS WINAPI SystemFunction006(LPCSTR password, LPSTR hash)
+{
+ CRYPT_LMhash(hash, password, strlen(password));
+
+ return STATUS_SUCCESS;
+}
reactos/lib/advapi32/crypt
diff -N crypt_md4.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt_md4.c 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2001 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 Hans Leidekker
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This code implements the MD4 message-digest algorithm.
+ * It is based on code in the public domain written by Colin
+ * Plumb in 1993. The algorithm is due to Ron Rivest.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD4_CTX structure, pass it to MD4Init, call MD4Update as
+ * needed on buffers full of bytes, and then call MD4Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+
+typedef struct
+{
+ unsigned int buf[4];
+ unsigned int i[2];
+ unsigned char in[64];
+ unsigned char digest[16];
+} MD4_CTX;
+
+
+/* The three core functions */
+
+#define rotl32(x,n) (((x) << ((unsigned int)(n))) | ((x) >> (32 - (unsigned int)(n))))
+
+#define F( x, y, z ) (((x) & (y)) | ((~x) & (z)))
+#define G( x, y, z ) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H( x, y, z ) ((x) ^ (y) ^ (z))
+
+#define FF( a, b, c, d, x, s ) { \
+ (a) += F( (b), (c), (d) ) + (x); \
+ (a) = rotl32( (a), (s) ); \
+ }
+#define GG( a, b, c, d, x, s ) { \
+ (a) += G( (b), (c), (d) ) + (x) + (unsigned int)0x5a827999; \
+ (a) = rotl32( (a), (s) ); \
+ }
+#define HH( a, b, c, d, x, s ) { \
+ (a) += H( (b), (c), (d) ) + (x) + (unsigned int)0x6ed9eba1; \
+ (a) = rotl32( (a), (s) ); \
+ }
+
+/*
+ * The core of the MD4 algorithm
+ */
+static VOID MD4Transform(unsigned int buf[4], const unsigned int in[16])
+{
+ register unsigned int a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ FF( a, b, c, d, in[0], 3 );
+ FF( d, a, b, c, in[1], 7 );
+ FF( c, d, a, b, in[2], 11 );
+ FF( b, c, d, a, in[3], 19 );
+ FF( a, b, c, d, in[4], 3 );
+ FF( d, a, b, c, in[5], 7 );
+ FF( c, d, a, b, in[6], 11 );
+ FF( b, c, d, a, in[7], 19 );
+ FF( a, b, c, d, in[8], 3 );
+ FF( d, a, b, c, in[9], 7 );
+ FF( c, d, a, b, in[10], 11 );
+ FF( b, c, d, a, in[11], 19 );
+ FF( a, b, c, d, in[12], 3 );
+ FF( d, a, b, c, in[13], 7 );
+ FF( c, d, a, b, in[14], 11 );
+ FF( b, c, d, a, in[15], 19 );
+
+ GG( a, b, c, d, in[0], 3 );
+ GG( d, a, b, c, in[4], 5 );
+ GG( c, d, a, b, in[8], 9 );
+ GG( b, c, d, a, in[12], 13 );
+ GG( a, b, c, d, in[1], 3 );
+ GG( d, a, b, c, in[5], 5 );
+ GG( c, d, a, b, in[9], 9 );
+ GG( b, c, d, a, in[13], 13 );
+ GG( a, b, c, d, in[2], 3 );
+ GG( d, a, b, c, in[6], 5 );
+ GG( c, d, a, b, in[10], 9 );
+ GG( b, c, d, a, in[14], 13 );
+ GG( a, b, c, d, in[3], 3 );
+ GG( d, a, b, c, in[7], 5 );
+ GG( c, d, a, b, in[11], 9 );
+ GG( b, c, d, a, in[15], 13 );
+
+ HH( a, b, c, d, in[0], 3 );
+ HH( d, a, b, c, in[8], 9 );
+ HH( c, d, a, b, in[4], 11 );
+ HH( b, c, d, a, in[12], 15 );
+ HH( a, b, c, d, in[2], 3 );
+ HH( d, a, b, c, in[10], 9 );
+ HH( c, d, a, b, in[6], 11 );
+ HH( b, c, d, a, in[14], 15 );
+ HH( a, b, c, d, in[1], 3 );
+ HH( d, a, b, c, in[9], 9 );
+ HH( c, d, a, b, in[5], 11 );
+ HH( b, c, d, a, in[13], 15 );
+ HH( a, b, c, d, in[3], 3 );
+ HH( d, a, b, c, in[11], 9 );
+ HH( c, d, a, b, in[7], 11 );
+ HH( b, c, d, a, in[15], 15 );
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static VOID byteReverse(unsigned char *buf, unsigned longs)
+{
+ unsigned int t;
+
+ do
+ {
+ t = (unsigned int)((unsigned)buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned)buf[1] << 8 | buf[0]);
+ *(unsigned int *)buf = t;
+ buf += 4;
+ } while (--longs);
+}
+
+/*
+ * Start MD4 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+VOID WINAPI MD4Init(MD4_CTX *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->i[0] = ctx->i[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+VOID WINAPI MD4Update(MD4_CTX *ctx, const unsigned char *buf, unsigned int len)
+{
+ register unsigned int t;
+
+ /* Update bitcount */
+ t = ctx->i[0];
+
+ if ((ctx->i[0] = t + ((unsigned int)len << 3)) < t)
+ ctx->i[1]++; /* Carry from low to high */
+
+ ctx->i[1] += len >> 29;
+ t = (t >> 3) & 0x3f;
+
+ /* Handle any leading odd-sized chunks */
+ if (t)
+ {
+ unsigned char *p = (unsigned char *)ctx->in + t;
+ t = 64 - t;
+
+ if (len < t)
+ {
+ memcpy(p, buf, len);
+ return;
+ }
+
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+
+ MD4Transform(ctx->buf, (unsigned int *)ctx->in);
+
+ buf += t;
+ len -= t;
+ }
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64)
+ {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+
+ MD4Transform(ctx->buf, (unsigned int *)ctx->in);
+
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+VOID WINAPI MD4Final(MD4_CTX *ctx)
+{
+ unsigned int count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->i[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8)
+ {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset( p, 0, count );
+ byteReverse(ctx->in, 16);
+ MD4Transform(ctx->buf, (unsigned int *)ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ }
+ else
+ {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((unsigned int *)ctx->in)[14] = ctx->i[0];
+ ((unsigned int *)ctx->in)[15] = ctx->i[1];
+
+ MD4Transform( ctx->buf, (unsigned int *)ctx->in );
+ byteReverse( (unsigned char *)ctx->buf, 4 );
+ memcpy(ctx->digest, ctx->buf, 16);
+}
reactos/lib/advapi32/crypt
diff -N crypt_md5.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt_md5.c 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2001 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 Hans Leidekker
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * It is based on code in the public domain written by Colin
+ * Plumb in 1993. The algorithm is due to Ron Rivest.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5_CTX structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+
+typedef struct
+{
+ unsigned int i[2];
+ unsigned int buf[4];
+ unsigned char in[64];
+ unsigned char digest[16];
+} MD5_CTX;
+
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1( x, y, z ) (x & y | ~x & z) */
+#define F1( x, y, z ) (z ^ (x & (y ^ z)))
+#define F2( x, y, z ) F1( z, x, y )
+#define F3( x, y, z ) (x ^ y ^ z)
+#define F4( x, y, z ) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP( f, w, x, y, z, data, s ) \
+ ( w += f( x, y, z ) + data, w = w << s | w >> (32 - s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(unsigned int buf[4], const unsigned int in[16])
+{
+ register unsigned int a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP( F1, a, b, c, d, in[0] + 0xd76aa478, 7 );
+ MD5STEP( F1, d, a, b, c, in[1] + 0xe8c7b756, 12 );
+ MD5STEP( F1, c, d, a, b, in[2] + 0x242070db, 17 );
+ MD5STEP( F1, b, c, d, a, in[3] + 0xc1bdceee, 22 );
+ MD5STEP( F1, a, b, c, d, in[4] + 0xf57c0faf, 7 );
+ MD5STEP( F1, d, a, b, c, in[5] + 0x4787c62a, 12 );
+ MD5STEP( F1, c, d, a, b, in[6] + 0xa8304613, 17 );
+ MD5STEP( F1, b, c, d, a, in[7] + 0xfd469501, 22 );
+ MD5STEP( F1, a, b, c, d, in[8] + 0x698098d8, 7 );
+ MD5STEP( F1, d, a, b, c, in[9] + 0x8b44f7af, 12 );
+ MD5STEP( F1, c, d, a, b, in[10] + 0xffff5bb1, 17 );
+ MD5STEP( F1, b, c, d, a, in[11] + 0x895cd7be, 22 );
+ MD5STEP( F1, a, b, c, d, in[12] + 0x6b901122, 7 );
+ MD5STEP( F1, d, a, b, c, in[13] + 0xfd987193, 12 );
+ MD5STEP( F1, c, d, a, b, in[14] + 0xa679438e, 17 );
+ MD5STEP( F1, b, c, d, a, in[15] + 0x49b40821, 22 );
+
+ MD5STEP( F2, a, b, c, d, in[1] + 0xf61e2562, 5 );
+ MD5STEP( F2, d, a, b, c, in[6] + 0xc040b340, 9 );
+ MD5STEP( F2, c, d, a, b, in[11] + 0x265e5a51, 14 );
+ MD5STEP( F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20 );
+ MD5STEP( F2, a, b, c, d, in[5] + 0xd62f105d, 5 );
+ MD5STEP( F2, d, a, b, c, in[10] + 0x02441453, 9 );
+ MD5STEP( F2, c, d, a, b, in[15] + 0xd8a1e681, 14 );
+ MD5STEP( F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20 );
+ MD5STEP( F2, a, b, c, d, in[9] + 0x21e1cde6, 5 );
+ MD5STEP( F2, d, a, b, c, in[14] + 0xc33707d6, 9 );
+ MD5STEP( F2, c, d, a, b, in[3] + 0xf4d50d87, 14 );
+ MD5STEP( F2, b, c, d, a, in[8] + 0x455a14ed, 20 );
+ MD5STEP( F2, a, b, c, d, in[13] + 0xa9e3e905, 5 );
+ MD5STEP( F2, d, a, b, c, in[2] + 0xfcefa3f8, 9 );
+ MD5STEP( F2, c, d, a, b, in[7] + 0x676f02d9, 14 );
+ MD5STEP( F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20 );
+
+ MD5STEP( F3, a, b, c, d, in[5] + 0xfffa3942, 4 );
+ MD5STEP( F3, d, a, b, c, in[8] + 0x8771f681, 11 );
+ MD5STEP( F3, c, d, a, b, in[11] + 0x6d9d6122, 16 );
+ MD5STEP( F3, b, c, d, a, in[14] + 0xfde5380c, 23 );
+ MD5STEP( F3, a, b, c, d, in[1] + 0xa4beea44, 4 );
+ MD5STEP( F3, d, a, b, c, in[4] + 0x4bdecfa9, 11 );
+ MD5STEP( F3, c, d, a, b, in[7] + 0xf6bb4b60, 16 );
+ MD5STEP( F3, b, c, d, a, in[10] + 0xbebfbc70, 23 );
+ MD5STEP( F3, a, b, c, d, in[13] + 0x289b7ec6, 4 );
+ MD5STEP( F3, d, a, b, c, in[0] + 0xeaa127fa, 11 );
+ MD5STEP( F3, c, d, a, b, in[3] + 0xd4ef3085, 16 );
+ MD5STEP( F3, b, c, d, a, in[6] + 0x04881d05, 23 );
+ MD5STEP( F3, a, b, c, d, in[9] + 0xd9d4d039, 4 );
+ MD5STEP( F3, d, a, b, c, in[12] + 0xe6db99e5, 11 );
+ MD5STEP( F3, c, d, a, b, in[15] + 0x1fa27cf8, 16 );
+ MD5STEP( F3, b, c, d, a, in[2] + 0xc4ac5665, 23 );
+
+ MD5STEP( F4, a, b, c, d, in[0] + 0xf4292244, 6 );
+ MD5STEP( F4, d, a, b, c, in[7] + 0x432aff97, 10 );
+ MD5STEP( F4, c, d, a, b, in[14] + 0xab9423a7, 15 );
+ MD5STEP( F4, b, c, d, a, in[5] + 0xfc93a039, 21 );
+ MD5STEP( F4, a, b, c, d, in[12] + 0x655b59c3, 6 );
+ MD5STEP( F4, d, a, b, c, in[3] + 0x8f0ccc92, 10 );
+ MD5STEP( F4, c, d, a, b, in[10] + 0xffeff47d, 15 );
+ MD5STEP( F4, b, c, d, a, in[1] + 0x85845dd1, 21 );
+ MD5STEP( F4, a, b, c, d, in[8] + 0x6fa87e4f, 6 );
+ MD5STEP( F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10 );
+ MD5STEP( F4, c, d, a, b, in[6] + 0xa3014314, 15 );
+ MD5STEP( F4, b, c, d, a, in[13] + 0x4e0811a1, 21 );
+ MD5STEP( F4, a, b, c, d, in[4] + 0xf7537e82, 6 );
+ MD5STEP( F4, d, a, b, c, in[11] + 0xbd3af235, 10 );
+ MD5STEP( F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15 );
+ MD5STEP( F4, b, c, d, a, in[9] + 0xeb86d391, 21 );
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static VOID byteReverse(unsigned char *buf, unsigned longs)
+{
+ unsigned int t;
+
+ do
+ {
+ t = (unsigned int)((unsigned)buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned)buf[1] << 8 | buf[0]);
+ *(unsigned int *)buf = t;
+ buf += 4;
+ } while (--longs);
+}
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+VOID WINAPI MD5Init(MD5_CTX *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->i[0] = ctx->i[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+VOID WINAPI MD5Update(MD5_CTX *ctx, const unsigned char *buf, unsigned int len)
+{
+ register unsigned int t;
+
+ /* Update bitcount */
+ t = ctx->i[0];
+
+ if ((ctx->i[0] = t + ((unsigned int)len << 3)) < t)
+ ctx->i[1]++; /* Carry from low to high */
+
+ ctx->i[1] += len >> 29;
+ t = (t >> 3) & 0x3f;
+
+ /* Handle any leading odd-sized chunks */
+ if (t)
+ {
+ unsigned char *p = (unsigned char *)ctx->in + t;
+ t = 64 - t;
+
+ if (len < t)
+ {
+ memcpy(p, buf, len);
+ return;
+ }
+
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+
+ MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+
+ buf += t;
+ len -= t;
+ }
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64)
+ {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+
+ MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+VOID WINAPI MD5Final( MD5_CTX *ctx )
+{
+ unsigned int count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->i[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8)
+ {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ }
+ else
+ {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((unsigned int *)ctx->in)[14] = ctx->i[0];
+ ((unsigned int *)ctx->in)[15] = ctx->i[1];
+
+ MD5Transform(ctx->buf, (unsigned int *)ctx->in);
+ byteReverse((unsigned char *)ctx->buf, 4);
+ memcpy(ctx->digest, ctx->buf, 16);
+}
reactos/lib/advapi32/crypt
diff -N crypt_sha.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ crypt_sha.c 13 Dec 2004 16:18:25 -0000 1.2.2.1
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2004 Filip Navara
+ * Based on public domain SHA code by Steve Reid <steve@edmweb.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "advapi32.h"
+#include "crypt.h"
+
+
+/* SHA Context Structure Declaration */
+
+typedef struct {
+ ULONG Unknown[6];
+ ULONG State[5];
+ ULONG Count[2];
+ UCHAR Buffer[64];
+} SHA_CTX, *PSHA_CTX;
+
+/* SHA1 Helper Macros */
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+/* FIXME: This definition of DWORD2BE is little endian specific! */
+#define DWORD2BE(x) (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000);
+/* FIXME: This definition of blk0 is little endian specific! */
+#define blk0(i) (Block[i] = (rol(Block[i],24)&0xFF00FF00)|(rol(Block[i],8)&0x00FF00FF))
+#define blk1(i) (Block[i&15] = rol(Block[(i+13)&15]^Block[(i+8)&15]^Block[(i+2)&15]^Block[i&15],1))
+#define f1(x,y,z) (z^(x&(y^z)))
+#define f2(x,y,z) (x^y^z)
+#define f3(x,y,z) ((x&y)|(z&(x|y)))
+#define f4(x,y,z) (x^y^z)
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+static VOID
+SHA1Transform(ULONG State[5], CHAR Buffer[64])
+{
+ ULONG a, b, c, d, e;
+ ULONG *Block;
+
+ Block = (ULONG*)Buffer;
+
+ /* Copy Context->State[] to working variables */
+ a = State[0];
+ b = State[1];
+ c = State[2];
+ d = State[3];
+ e = State[4];
+
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+
+ /* Add the working variables back into Context->State[] */
+ State[0] += a;
+ State[1] += b;
+ State[2] += c;
+ State[3] += d;
+ State[4] += e;
+
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/******************************************************************************
+ * A_SHAInit [ADVAPI32.@]
+ *
+ * Initialize a SHA context structure.
+ */
+VOID WINAPI
+A_SHAInit(PSHA_CTX Context)
+{
+ /* SHA1 initialization constants */
+ Context->State[0] = 0x67452301;
+ Context->State[1] = 0xEFCDAB89;
+ Context->State[2] = 0x98BADCFE;
+ Context->State[3] = 0x10325476;
+ Context->State[4] = 0xC3D2E1F0;
+ Context->Count[0] =
+ Context->Count[1] = 0;
+}
+
+/******************************************************************************
+ * A_SHAUpdate [ADVAPI32.@]
+ *
+ * Update a SHA context with a hashed data from supplied buffer.
+ */
+VOID WINAPI
+A_SHAUpdate(PSHA_CTX Context, PCHAR Buffer, UINT BufferSize)
+{
+ ULONG BufferContentSize;
+
+ BufferContentSize = Context->Count[1] & 63;
+ Context->Count[1] += BufferSize;
+ if (Context->Count[1] < BufferSize)
+ Context->Count[0]++;
+ Context->Count[0] += (BufferSize >> 29);
+
+ if (BufferContentSize + BufferSize < 64)
+ {
+ RtlCopyMemory(&Context->Buffer[BufferContentSize], Buffer,
+ BufferSize);
+ }
+ else
+ {
+ while (BufferContentSize + BufferSize >= 64)
+ {
+ RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer,
+ 64 - BufferContentSize);
+ Buffer += 64 - BufferContentSize;
+ BufferSize -= 64 - BufferContentSize;
+ SHA1Transform(Context->State, Context->Buffer);
+ BufferContentSize = 0;
+ }
+ RtlCopyMemory(Context->Buffer + BufferContentSize, Buffer, BufferSize);
+ }
+}
+
+/******************************************************************************
+ * A_SHAFinal [ADVAPI32.@]
+ *
+ * Finalize SHA context and return the resulting hash.
+ */
+VOID WINAPI
+A_SHAFinal(PSHA_CTX Context, PULONG Result)
+{
+ INT Pad, Index;
+ UCHAR Buffer[72];
+ ULONG *Count;
+ ULONG BufferContentSize, LengthHi, LengthLo;
+
+ BufferContentSize = Context->Count[1] & 63;
+ if (BufferContentSize >= 56)
+ Pad = 56 + 64 - BufferContentSize;
+ else
+ Pad = 56 - BufferContentSize;
+
+ LengthHi = (Context->Count[0] << 3) | (Context->Count[1] >> (32 - 3));
+ LengthLo = (Context->Count[1] << 3);
+
+ RtlZeroMemory(Buffer + 1, Pad - 1);
+ Buffer[0] = 0x80;
+ Count = (ULONG*)(Buffer + Pad);
+ Count[0] = DWORD2BE(LengthHi);
+ Count[1] = DWORD2BE(LengthLo);
+ A_SHAUpdate(Context, Buffer, Pad + 8);
+
+ for (Index = 0; Index < 5; Index++)
+ Result[Index] = DWORD2BE(Context->State[Index]);
+
+ A_SHAInit(Context);
+}
reactos/lib/dinput8
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:25 -0000 1.1.2.1
@@ -0,0 +1,11 @@
+*.coff
+*.dll
+*.d
+*.a
+*.o
+*.sym
+*.map
+*.tmp
+Makefile.ros
+dinput8.spec.def
+dinput8.stubs.c
reactos/lib/dinput8
diff -N Makefile.in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.in 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,16 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = dinput8.dll
+IMPORTS = dinput
+EXTRALIBS = -luuid
+
+C_SRCS = \
+ dinput8_main.c
+
+RC_SRCS = version.rc
+
+@MAKE_DLL_RULES@
+
+### Dependencies:
reactos/lib/dinput8
diff -N Makefile.ros-template
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.ros-template 13 Dec 2004 16:18:26 -0000 1.2.2.1
@@ -0,0 +1,28 @@
+# $Id: Makefile.ros-template,v 1.2.2.1 2004/12/13 16:18:26 hyperion Exp $
+
+TARGET_NAME = dinput8
+
+TARGET_OBJECTS = @C_SRCS@
+
+TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
+
+TARGET_SDKLIBS = wine.a @IMPORTS@ ole32.a wine_uuid.a ntdll.a winmm.a dxguid.a
+
+
+
+TARGET_RC_SRCS = @RC_SRCS@
+TARGET_RC_BINSRC = @RC_BINSRC@
+TARGET_RC_BINARIES = @RC_BINARIES@
+
+default: all
+
+authors.c:
+ifeq ($(HOST),mingw32-linux)
+ echo 'const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 };' > authors.c
+else
+ echo const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 }; > authors.c
+endif
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
+
+include $(TOOLS_PATH)/depend.mk
reactos/lib/dinput8
diff -N dinput8.spec
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dinput8.spec 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,5 @@
+@ stdcall DirectInput8Create(long long ptr ptr ptr)
+@ stdcall -private DllCanUnloadNow() DINPUT8_DllCanUnloadNow
+@ stdcall -private DllGetClassObject(ptr ptr ptr) DINPUT8_DllGetClassObject
+@ stdcall -private DllRegisterServer() DINPUT8_DllRegisterServer
+@ stdcall -private DllUnregisterServer() DINPUT8_DllUnregisterServer
reactos/lib/dinput8
diff -N dinput8_main.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dinput8_main.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,83 @@
+/* DirectInput 8
+ *
+ * Copyright 2002 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "wine/debug.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "dinput.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+/******************************************************************************
+ * DirectInput8Create (DINPUT8.@)
+ */
+HRESULT WINAPI DirectInput8Create(
+ HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
+ LPUNKNOWN punkOuter
+) {
+ return DirectInputCreateEx(hinst, dwVersion, riid, ppDI, punkOuter);
+}
+
+/***********************************************************************
+ * DllCanUnloadNow (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllCanUnloadNow(void)
+{
+ FIXME("(void): stub\n");
+
+ return S_FALSE;
+}
+
+/***********************************************************************
+ * DllGetClassObject (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllGetClassObject(REFCLSID rclsid, REFIID riid,
+ LPVOID *ppv)
+{
+ FIXME("(%p, %p, %p): stub\n", debugstr_guid(rclsid),
+ debugstr_guid(riid), ppv);
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+/***********************************************************************
+ * DllRegisterServer (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllRegisterServer(void)
+{
+ FIXME("(void): stub\n");
+
+ return S_OK;
+}
+
+/***********************************************************************
+ * DllUnregisterServer (DINPUT8.@)
+ */
+HRESULT WINAPI DINPUT8_DllUnregisterServer(void)
+{
+ FIXME("(void): stub\n");
+
+ return S_OK;
+}
reactos/lib/dinput8
diff -N makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ makefile 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,9 @@
+# $Id: makefile,v 1.1.2.1 2004/12/13 16:18:26 hyperion Exp $
+
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = winedll
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
reactos/lib/dinput8
diff -N version.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ version.rc 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004 Tom Wickline
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine DirectInput 8"
+#define WINE_FILENAME_STR "dinput8.dll"
+#define WINE_FILEVERSION 5,1,2600,881
+#define WINE_FILEVERSION_STR "5.1.2600.881"
+#define WINE_PRODUCTVERSION 5,1,2600,881
+#define WINE_PRODUCTVERSION_STR "5.1"
+#define WINE_PRODUCTNAME_STR "DirectX"
+
+#include "wine/wine_common_ver.rc"
reactos/lib/dinput8
diff -N winehq2ros.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,14 @@
+Index: version.rc
+===================================================================
+RCS file: /home/wine/wine/dlls/dinput8/version.rc,v
+retrieving revision 1.4
+diff -u -r1.4 version.rc
+--- version.rc 23 Nov 2004 13:59:36 -0000 1.4
++++ version.rc 7 Dec 2004 22:27:53 -0000
+@@ -22,5 +22,6 @@
+ #define WINE_FILEVERSION_STR "5.1.2600.881"
+ #define WINE_PRODUCTVERSION 5,1,2600,881
+ #define WINE_PRODUCTVERSION_STR "5.1"
++#define WINE_PRODUCTNAME_STR "DirectX"
+
+ #include "wine/wine_common_ver.rc"
reactos/lib/msi
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:26 -0000 1.2.2.1
@@ -0,0 +1,11 @@
+*.coff
+*.dll
+*.d
+*.a
+*.o
+*.sym
+*.map
+*.tmp
+Makefile.ros
+msi.spec.def
+msi.stubs.c
reactos/lib/msi
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,9 @@
+# $Id: Makefile,v 1.1.2.1 2004/12/13 16:18:26 hyperion Exp $
+
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = winedll
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
reactos/lib/msi
diff -N Makefile.in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.in 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,50 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = msi.dll
+IMPORTS = shell32 cabinet oleaut32 ole32 version user32 advapi32 kernel32
+EXTRALIBS = -luuid $(LIBUNICODE)
+
+C_SRCS = \
+ action.c \
+ create.c \
+ distinct.c \
+ handle.c \
+ insert.c \
+ msi.c \
+ msiquery.c \
+ order.c \
+ package.c \
+ record.c \
+ regsvr.c \
+ select.c \
+ string.c \
+ suminfo.c \
+ table.c \
+ tokenize.c \
+ update.c \
+ where.c
+
+RC_SRCS = version.rc
+
+EXTRA_SRCS = sql.y cond.y
+EXTRA_OBJS = sql.tab.o cond.tab.o
+
+@MAKE_DLL_RULES@
+
+sql.tab.c sql.tab.h: sql.y
+ $(BISON) -p SQL_ -d $(SRCDIR)/sql.y -o sql.tab.c
+
+cond.tab.c cond.tab.h: cond.y
+ $(BISON) -p COND_ -d $(SRCDIR)/cond.y -o cond.tab.c
+
+# hack to allow parallel make
+sql.tab.h: sql.tab.c
+sql.tab.o: sql.tab.h
+cond.tab.h: cond.tab.c
+cond.tab.o: cond.tab.h
+
+tokenize.o: sql.tab.h
+
+### Dependencies:
reactos/lib/msi
diff -N Makefile.ros-template
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.ros-template 13 Dec 2004 16:18:26 -0000 1.3.2.1
@@ -0,0 +1,39 @@
+# $Id: Makefile.ros-template
+
+TARGET_NAME = msi
+
+TARGET_OBJECTS = @C_SRCS@ @EXTRA_OBJS@
+
+TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
+
+TARGET_SDKLIBS = @IMPORTS@ winmm.a wine.a wine_uuid.a wine_unicode.a ntdll.a
+
+TARGET_BASE = $(TARGET_BASE_LIB_WINMM)
+
+TARGET_RC_SRCS = @RC_SRCS@
+TARGET_RC_BINSRC = @RC_BINSRC@
+TARGET_RC_BINARIES = @RC_BINARIES@
+
+#TARGET_CLEAN = *.tab.c *.tab.h
+
+default: all
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
+
+include $(TOOLS_PATH)/depend.mk
+
+#
+# Optional use of bison, this will allow independent building from
+# Wine.
+#
+# Bison is requiered for building msi.dll. If MingW32 for windows,
+# download bison from http://gnuwin32.sourceforge.net/
+# Make sure bison.exe is placed in your command path for execution.
+#
+#
+
+#sql.tab.c sql.tab.h: sql.y
+# bison -p SQL_ -d ./sql.y -o sql.tab.c
+
+#cond.tab.c cond.tab.h: cond.y
+# bison -p COND_ -d ./cond.y -o cond.tab.c
reactos/lib/msi
diff -N action.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ action.c 13 Dec 2004 16:18:26 -0000 1.3.2.1
@@ -0,0 +1,4877 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Pages I need
+ *
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/installexecutesequence_table.asp
+
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/standard_actions_reference.asp
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <fcntl.h>
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winreg.h"
+#include "wine/debug.h"
+#include "fdi.h"
+#include "msi.h"
+#include "msiquery.h"
+//#include "msvcrt/fcntl.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+#include "winuser.h"
+#include "shlobj.h"
+#include "wine/unicode.h"
+#include "ver.h"
+
+#define CUSTOM_ACTION_TYPE_MASK 0x3F
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tagMSIFEATURE
+{
+ WCHAR Feature[96];
+ WCHAR Feature_Parent[96];
+ WCHAR Title[0x100];
+ WCHAR Description[0x100];
+ INT Display;
+ INT Level;
+ WCHAR Directory[96];
+ INT Attributes;
+
+ INSTALLSTATE State;
+ BOOL Enabled;
+ INT ComponentCount;
+ INT Components[1024]; /* yes hardcoded limit.... I am bad */
+ INT Cost;
+} MSIFEATURE;
+
+typedef struct tagMSICOMPONENT
+{
+ WCHAR Component[96];
+ WCHAR ComponentId[96];
+ WCHAR Directory[96];
+ INT Attributes;
+ WCHAR Condition[0x100];
+ WCHAR KeyPath[96];
+
+ INSTALLSTATE State;
+ BOOL FeatureState;
+ BOOL Enabled;
+ INT Cost;
+} MSICOMPONENT;
+
+typedef struct tagMSIFOLDER
+{
+ WCHAR Directory[96];
+ WCHAR TargetDefault[96];
+ WCHAR SourceDefault[96];
+
+ WCHAR ResolvedTarget[MAX_PATH];
+ WCHAR ResolvedSource[MAX_PATH];
+ WCHAR Property[MAX_PATH]; /* initially set property */
+ INT ParentIndex;
+ INT State;
+ /* 0 = uninitialized */
+ /* 1 = existing */
+ /* 2 = created remove if empty */
+ /* 3 = created persist if empty */
+ INT Cost;
+ INT Space;
+}MSIFOLDER;
+
+typedef struct tagMSIFILE
+{
+ WCHAR File[72];
+ INT ComponentIndex;
+ WCHAR FileName[MAX_PATH];
+ INT FileSize;
+ WCHAR Version[72];
+ WCHAR Language[20];
+ INT Attributes;
+ INT Sequence;
+
+ INT State;
+ /* 0 = uninitialize */
+ /* 1 = not present */
+ /* 2 = present but replace */
+ /* 3 = present do not replace */
+ /* 4 = Installed */
+ WCHAR SourcePath[MAX_PATH];
+ WCHAR TargetPath[MAX_PATH];
+ BOOL Temporary;
+}MSIFILE;
+
+/*
+ * Prototypes
+ */
+static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran);
+static UINT ACTION_ProcessUISequence(MSIPACKAGE *package);
+
+UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action);
+
+static UINT ACTION_LaunchConditions(MSIPACKAGE *package);
+static UINT ACTION_CostInitialize(MSIPACKAGE *package);
+static UINT ACTION_CreateFolders(MSIPACKAGE *package);
+static UINT ACTION_CostFinalize(MSIPACKAGE *package);
+static UINT ACTION_FileCost(MSIPACKAGE *package);
+static UINT ACTION_InstallFiles(MSIPACKAGE *package);
+static UINT ACTION_DuplicateFiles(MSIPACKAGE *package);
+static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package);
+static UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action);
+static UINT ACTION_InstallInitialize(MSIPACKAGE *package);
+static UINT ACTION_InstallValidate(MSIPACKAGE *package);
+static UINT ACTION_ProcessComponents(MSIPACKAGE *package);
+static UINT ACTION_RegisterTypeLibraries(MSIPACKAGE *package);
+static UINT ACTION_RegisterClassInfo(MSIPACKAGE *package);
+static UINT ACTION_RegisterProgIdInfo(MSIPACKAGE *package);
+static UINT ACTION_CreateShortcuts(MSIPACKAGE *package);
+static UINT ACTION_PublishProduct(MSIPACKAGE *package);
+
+static UINT HANDLE_CustomType1(MSIPACKAGE *package, const LPWSTR source,
+ const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType2(MSIPACKAGE *package, const LPWSTR source,
+ const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType18(MSIPACKAGE *package, const LPWSTR source,
+ const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType50(MSIPACKAGE *package, const LPWSTR source,
+ const LPWSTR target, const INT type);
+static UINT HANDLE_CustomType34(MSIPACKAGE *package, const LPWSTR source,
+ const LPWSTR target, const INT type);
+
+static DWORD deformat_string(MSIPACKAGE *package, WCHAR* ptr,WCHAR** data);
+static UINT resolve_folder(MSIPACKAGE *package, LPCWSTR name, LPWSTR path,
+ BOOL source, BOOL set_prop, MSIFOLDER **folder);
+
+static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
+
+/*
+ * consts and values used
+ */
+static const WCHAR cszSourceDir[] = {'S','o','u','r','c','e','D','i','r',0};
+static const WCHAR cszRootDrive[] = {'R','O','O','T','D','R','I','V','E',0};
+static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};
+static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
+static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0};
+static const WCHAR c_collen[] = {'C',':','\\',0};
+
+static const WCHAR cszlsb[]={'[',0};
+static const WCHAR cszrsb[]={']',0};
+static const WCHAR cszbs[]={'\\',0};
+
+const static WCHAR szCreateFolders[] =
+ {'C','r','e','a','t','e','F','o','l','d','e','r','s',0};
+const static WCHAR szCostFinalize[] =
+ {'C','o','s','t','F','i','n','a','l','i','z','e',0};
+const static WCHAR szInstallFiles[] =
+ {'I','n','s','t','a','l','l','F','i','l','e','s',0};
+const static WCHAR szDuplicateFiles[] =
+ {'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
+const static WCHAR szWriteRegistryValues[] =
+{'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
+const static WCHAR szCostInitialize[] =
+ {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
+const static WCHAR szFileCost[] = {'F','i','l','e','C','o','s','t',0};
+const static WCHAR szInstallInitialize[] =
+ {'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};
+const static WCHAR szInstallValidate[] =
+ {'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
+const static WCHAR szLaunchConditions[] =
+ {'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
+const static WCHAR szProcessComponents[] =
+ {'P','r','o','c','e','s','s','C','o','m','p','o','n','e','n','t','s',0};
+const static WCHAR szRegisterTypeLibraries[] =
+{'R','e','g','i','s','t','e','r','T','y','p','e','L','i','b','r','a','r',
+'i','e','s',0};
+const static WCHAR szRegisterClassInfo[] =
+{'R','e','g','i','s','t','e','r','C','l','a','s','s','I','n','f','o',0};
+const static WCHAR szRegisterProgIdInfo[] =
+{'R','e','g','i','s','t','e','r','P','r','o','g','I','d','I','n','f','o',0};
+const static WCHAR szCreateShortcuts[] =
+{'C','r','e','a','t','e','S','h','o','r','t','c','u','t','s',0};
+const static WCHAR szPublishProduct[] =
+{'P','u','b','l','i','s','h','P','r','o','d','u','c','t',0};
+
+/********************************************************
+ * helper functions to get around current HACKS and such
+ ********************************************************/
+inline static void reduce_to_longfilename(WCHAR* filename)
+{
+ if (strchrW(filename,'|'))
+ {
+ WCHAR newname[MAX_PATH];
+ strcpyW(newname,strchrW(filename,'|')+1);
+ strcpyW(filename,newname);
+ }
+}
+
+inline static char *strdupWtoA( const WCHAR *str )
+{
+ char *ret = NULL;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL
+);
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
+ WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
+ }
+ return ret;
+}
+
+inline static WCHAR *strdupAtoW( const char *str )
+{
+ WCHAR *ret = NULL;
+ if (str)
+ {
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
+ MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len );
+ }
+ return ret;
+}
+
+inline static WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
+{
+ UINT rc;
+ DWORD sz;
+ LPWSTR ret;
+
+ sz = 0;
+ rc = MSI_RecordGetStringW(row,index,NULL,&sz);
+ if (sz <= 0)
+ return NULL;
+
+ sz ++;
+ ret = HeapAlloc(GetProcessHeap(),0,sz * sizeof (WCHAR));
+ rc = MSI_RecordGetStringW(row,index,ret,&sz);
+ return ret;
+}
+
+inline static int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
+{
+ int rc = -1;
+ DWORD i;
+
+ for (i = 0; i < package->loaded_components; i++)
+ {
+ if (strcmpW(Component,package->components[i].Component)==0)
+ {
+ rc = i;
+ break;
+ }
+ }
+ return rc;
+}
+
+inline static int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
+{
+ int rc = -1;
+ DWORD i;
+
+ for (i = 0; i < package->loaded_features; i++)
+ {
+ if (strcmpW(Feature,package->features[i].Feature)==0)
+ {
+ rc = i;
+ break;
+ }
+ }
+ return rc;
+}
+
+inline static int get_loaded_file(MSIPACKAGE* package, LPCWSTR file)
+{
+ int rc = -1;
+ DWORD i;
+
+ for (i = 0; i < package->loaded_files; i++)
+ {
+ if (strcmpW(file,package->files[i].File)==0)
+ {
+ rc = i;
+ break;
+ }
+ }
+ return rc;
+}
+
+static int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path)
+{
+ DWORD i;
+ DWORD index;
+
+ if (!package)
+ return -2;
+
+ for (i=0; i < package->loaded_files; i++)
+ if (strcmpW(package->files[i].File,name)==0)
+ return -1;
+
+ index = package->loaded_files;
+ package->loaded_files++;
+ if (package->loaded_files== 1)
+ package->files = HeapAlloc(GetProcessHeap(),0,sizeof(MSIFILE));
+ else
+ package->files = HeapReAlloc(GetProcessHeap(),0,
+ package->files , package->loaded_files * sizeof(MSIFILE));
+
+ memset(&package->files[index],0,sizeof(MSIFILE));
+
+ strcpyW(package->files[index].File,name);
+ strcpyW(package->files[index].TargetPath,path);
+ package->files[index].Temporary = TRUE;
+
+ TRACE("Tracking tempfile (%s)\n",debugstr_w(package->files[index].File));
+
+ return 0;
+}
+
+void ACTION_remove_tracked_tempfiles(MSIPACKAGE* package)
+{
+ DWORD i;
+
+ if (!package)
+ return;
+
+ for (i = 0; i < package->loaded_files; i++)
+ {
+ if (package->files[i].Temporary)
+ DeleteFileW(package->files[i].TargetPath);
+
+ }
+}
+
+static void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d )
+{
+ MSIRECORD * row;
+
+ row = MSI_CreateRecord(4);
+ MSI_RecordSetInteger(row,1,a);
+ MSI_RecordSetInteger(row,2,b);
+ MSI_RecordSetInteger(row,3,c);
+ MSI_RecordSetInteger(row,4,d);
+ MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
+ msiobj_release(&row->hdr);
+}
+
+static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
+{
+ static const WCHAR Query_t[] =
+{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o',
+'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',
+' ','\'','%','s','\'',0};
+ WCHAR message[1024];
+ UINT rc;
+ MSIQUERY * view;
+ MSIRECORD * row = 0;
+ static WCHAR *ActionFormat=NULL;
+ static WCHAR LastAction[0x100] = {0};
+ WCHAR Query[1024];
+ LPWSTR ptr;
+
+ if (strcmpW(LastAction,action)!=0)
+ {
+ sprintfW(Query,Query_t,action);
+ rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+ if (rc != ERROR_SUCCESS)
+ return;
+ rc = MSI_ViewExecute(view, 0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ return;
+ }
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ return;
+ }
+
+ if (MSI_RecordIsNull(row,3))
+ {
+ msiobj_release(&row->hdr);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return;
+ }
+
+ if (ActionFormat)
+ HeapFree(GetProcessHeap(),0,ActionFormat);
+
+ ActionFormat = load_dynamic_stringW(row,3);
+ strcpyW(LastAction,action);
+ msiobj_release(&row->hdr);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ }
+
+ message[0]=0;
+ ptr = ActionFormat;
+ while (*ptr)
+ {
+ LPWSTR ptr2;
+ LPWSTR data=NULL;
+ WCHAR tmp[1023];
+ INT field;
+
+ ptr2 = strchrW(ptr,'[');
+ if (ptr2)
+ {
+ strncpyW(tmp,ptr,ptr2-ptr);
+ tmp[ptr2-ptr]=0;
+ strcatW(message,tmp);
+ ptr2++;
+ field = atoiW(ptr2);
+ data = load_dynamic_stringW(record,field);
+ if (data)
+ {
+ strcatW(message,data);
+ HeapFree(GetProcessHeap(),0,data);
+ }
+ ptr=strchrW(ptr2,']');
+ ptr++;
+ }
+ else
+ {
+ strcatW(message,ptr);
+ break;
+ }
+ }
+
+ row = MSI_CreateRecord(1);
+ MSI_RecordSetStringW(row,1,message);
+
+ MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);
+ msiobj_release(&row->hdr);
+}
+
+
+static void ui_actionstart(MSIPACKAGE *package, LPCWSTR action)
+{
+ static const WCHAR template_s[]=
+{'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ','%','s','.',0};
+ static const WCHAR format[] =
+{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
+ static const WCHAR Query_t[] =
+{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o',
+'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',
+' ','\'','%','s','\'',0};
+ WCHAR message[1024];
+ WCHAR timet[0x100];
+ UINT rc;
+ MSIQUERY * view;
+ MSIRECORD * row = 0;
+ WCHAR *ActionText=NULL;
+ WCHAR Query[1024];
+
+ GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
+
+ sprintfW(Query,Query_t,action);
+ rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+ if (rc != ERROR_SUCCESS)
+ return;
+ rc = MSI_ViewExecute(view, 0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return;
+ }
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return;
+ }
+
+ ActionText = load_dynamic_stringW(row,2);
+ msiobj_release(&row->hdr);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+
+ sprintfW(message,template_s,timet,action,ActionText);
+
+ row = MSI_CreateRecord(1);
+ MSI_RecordSetStringW(row,1,message);
+
+ MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, row);
+ msiobj_release(&row->hdr);
+ HeapFree(GetProcessHeap(),0,ActionText);
+}
+
+static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
+ UINT rc)
+{
+ MSIRECORD * row;
+ static const WCHAR template_s[]=
+{'A','c','t','i','o','n',' ','s','t','a','r','t',' ','%','s',':',' ','%','s',
+'.',0};
+ static const WCHAR template_e[]=
+{'A','c','t','i','o','n',' ','e','n','d','e','d',' ','%','s',':',' ','%','s',
+'.',' ','R','e','t','u','r','n',' ','v','a','l','u','e',' ','%','i','.',0};
+ static const WCHAR format[] =
+{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
+ WCHAR message[1024];
+ WCHAR timet[0x100];
+
+ GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
+ if (start)
+ sprintfW(message,template_s,timet,action);
+ else
+ sprintfW(message,template_e,timet,action,rc);
+
+ row = MSI_CreateRecord(1);
+ MSI_RecordSetStringW(row,1,message);
+
+ MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
+ msiobj_release(&row->hdr);
+}
+
+/****************************************************
+ * TOP level entry points
+ *****************************************************/
+
+UINT ACTION_DoTopLevelINSTALL(MSIPACKAGE *package, LPCWSTR szPackagePath,
+ LPCWSTR szCommandLine)
+{
+ DWORD sz;
+ WCHAR buffer[10];
+ UINT rc;
+ static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
+
+ if (szPackagePath)
+ {
+ LPWSTR p;
+ WCHAR check[MAX_PATH];
+ WCHAR pth[MAX_PATH];
+ DWORD size;
+
+ strcpyW(pth,szPackagePath);
+ p = strrchrW(pth,'\\');
+ if (p)
+ {
+ p++;
+ *p=0;
+ }
+
+ size = MAX_PATH;
+ if (MSI_GetPropertyW(package,cszSourceDir,check,&size)
+ != ERROR_SUCCESS )
+ MSI_SetPropertyW(package, cszSourceDir, pth);
+ }
+
+ if (szCommandLine)
+ {
+ LPWSTR ptr,ptr2;
+ ptr = (LPWSTR)szCommandLine;
+
+ while (*ptr)
+ {
+ WCHAR prop[0x100];
+ WCHAR val[0x100];
+
+ TRACE("Looking at %s\n",debugstr_w(ptr));
+
+ ptr2 = strchrW(ptr,'=');
+ if (ptr2)
+ {
+ BOOL quote=FALSE;
+ DWORD len = 0;
+
+ while (*ptr == ' ') ptr++;
+ strncpyW(prop,ptr,ptr2-ptr);
+ prop[ptr2-ptr]=0;
+ ptr2++;
+
+ ptr = ptr2;
+ while (*ptr && (quote || (!quote && *ptr!=' ')))
+ {
+ if (*ptr == '"')
+ quote = !quote;
+ ptr++;
+ len++;
+ }
+
+ if (*ptr2=='"')
+ {
+ ptr2++;
+ len -= 2;
+ }
+ strncpyW(val,ptr2,len);
+ val[len]=0;
+
+ if (strlenW(prop) > 0)
+ {
+ TRACE("Found commandline property (%s) = (%s)\n", debugstr_w(prop), debugstr_w(val));
+ MSI_SetPropertyW(package,prop,val);
+ }
+ }
+ ptr++;
+ }
+ }
+
+ sz = 10;
+ if (MSI_GetPropertyW(package,szUILevel,buffer,&sz) == ERROR_SUCCESS)
+ {
+ if (atoiW(buffer) >= INSTALLUILEVEL_REDUCED)
+ {
+ rc = ACTION_ProcessUISequence(package);
+ if (rc == ERROR_SUCCESS)
+ rc = ACTION_ProcessExecSequence(package,TRUE);
+ }
+ else
+ rc = ACTION_ProcessExecSequence(package,FALSE);
+ }
+ else
+ rc = ACTION_ProcessExecSequence(package,FALSE);
+
+ return rc;
+}
+
+
+static UINT ACTION_ProcessExecSequence(MSIPACKAGE *package, BOOL UIran)
+{
+ MSIQUERY * view;
+ UINT rc;
+ static const WCHAR ExecSeqQuery[] = {
+ 's','e','l','e','c','t',' ','*',' ',
+ 'f','r','o','m',' ',
+ 'I','n','s','t','a','l','l','E','x','e','c','u','t','e',
+ 'S','e','q','u','e','n','c','e',' ',
+ 'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ',
+ '>',' ','%','i',' ','o','r','d','e','r',' ',
+ 'b','y',' ','S','e','q','u','e','n','c','e',0 };
+ WCHAR Query[1024];
+ MSIRECORD * row = 0;
+ static const WCHAR IVQuery[] = {
+ 's','e','l','e','c','t',' ','S','e','q','u','e','n','c','e',' ',
+ 'f','r','o','m',' ','I','n','s','t','a','l','l',
+ 'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e',' ',
+ 'w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',' ',
+ '`','I','n','s','t','a','l','l','V','a','l','i','d','a','t','e','`',
+ 0};
+
+ if (UIran)
+ {
+ INT seq = 0;
+
+ rc = MSI_DatabaseOpenViewW(package->db, IVQuery, &view);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+ rc = MSI_ViewExecute(view, 0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return rc;
+ }
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return rc;
+ }
+ seq = MSI_RecordGetInteger(row,1);
+ msiobj_release(&row->hdr);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ sprintfW(Query,ExecSeqQuery,seq);
+ }
+ else
+ sprintfW(Query,ExecSeqQuery,0);
+
+ rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = MSI_ViewExecute(view, 0);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ goto end;
+ }
+
+ TRACE("Running the actions \n");
+
+ while (1)
+ {
+ WCHAR buffer[0x100];
+ DWORD sz = 0x100;
+
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ {
+ rc = ERROR_SUCCESS;
+ break;
+ }
+
+ /* check conditions */
+ if (!MSI_RecordIsNull(row,2))
+ {
+ LPWSTR cond = NULL;
+ cond = load_dynamic_stringW(row,2);
+
+ if (cond)
+ {
+ /* this is a hack to skip errors in the condition code */
+ if (MSI_EvaluateConditionW(package, cond) ==
+ MSICONDITION_FALSE)
+ {
+ HeapFree(GetProcessHeap(),0,cond);
+ msiobj_release(&row->hdr);
+ continue;
+ }
+ else
+ HeapFree(GetProcessHeap(),0,cond);
+ }
+ }
+
+ sz=0x100;
+ rc = MSI_RecordGetStringW(row,1,buffer,&sz);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Error is %x\n",rc);
+ msiobj_release(&row->hdr);
+ break;
+ }
+
+ rc = ACTION_PerformAction(package,buffer);
+
+ if (rc == ERROR_FUNCTION_NOT_CALLED)
+ rc = ERROR_SUCCESS;
+
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Execution halted due to error (%i)\n",rc);
+ msiobj_release(&row->hdr);
+ break;
+ }
+
+ msiobj_release(&row->hdr);
+ }
+
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ }
+
+end:
+ return rc;
+}
+
+
+static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)
+{
+ MSIQUERY * view;
+ UINT rc;
+ static const WCHAR ExecSeqQuery [] = {
+ 's','e','l','e','c','t',' ','*',' ',
+ 'f','r','o','m',' ','I','n','s','t','a','l','l',
+ 'U','I','S','e','q','u','e','n','c','e',' ',
+ 'w','h','e','r','e',' ','S','e','q','u','e','n','c','e',' ', '>',' ','0',' ',
+ 'o','r','d','e','r',' ','b','y',' ','S','e','q','u','e','n','c','e',0};
+
+ rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = MSI_ViewExecute(view, 0);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ goto end;
+ }
+
+ TRACE("Running the actions \n");
+
+ while (1)
+ {
+ WCHAR buffer[0x100];
+ DWORD sz = 0x100;
+ MSIRECORD * row = 0;
+
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ {
+ rc = ERROR_SUCCESS;
+ break;
+ }
+
+ /* check conditions */
+ if (!MSI_RecordIsNull(row,2))
+ {
+ LPWSTR cond = NULL;
+ cond = load_dynamic_stringW(row,2);
+
+ if (cond)
+ {
+ /* this is a hack to skip errors in the condition code */
+ if (MSI_EvaluateConditionW(package, cond) ==
+ MSICONDITION_FALSE)
+ {
+ HeapFree(GetProcessHeap(),0,cond);
+ msiobj_release(&row->hdr);
+ continue;
+ }
+ else
+ HeapFree(GetProcessHeap(),0,cond);
+ }
+ }
+
+ sz=0x100;
+ rc = MSI_RecordGetStringW(row,1,buffer,&sz);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Error is %x\n",rc);
+ msiobj_release(&row->hdr);
+ break;
+ }
+
+ rc = ACTION_PerformAction(package,buffer);
+
+ if (rc == ERROR_FUNCTION_NOT_CALLED)
+ rc = ERROR_SUCCESS;
+
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Execution halted due to error (%i)\n",rc);
+ msiobj_release(&row->hdr);
+ break;
+ }
+
+ msiobj_release(&row->hdr);
+ }
+
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ }
+
+end:
+ return rc;
+}
+
+/********************************************************
+ * ACTION helper functions and functions that perform the actions
+ *******************************************************/
+
+/*
+ * Alot of actions are really important even if they don't do anything
+ * explicit.. Lots of properties are set at the beginning of the installation
+ * CostFinalize does a bunch of work to translated the directories and such
+ *
+ * But until I get write access to the database that is hard, so I am going to
+ * hack it to see if I can get something to run.
+ */
+UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action)
+{
+ UINT rc = ERROR_SUCCESS;
+
+ TRACE("Performing action (%s)\n",debugstr_w(action));
+ ui_actioninfo(package, action, TRUE, 0);
+ ui_actionstart(package, action);
+ ui_progress(package,2,1,0,0);
+
+ /* pre install, setup and configuration block */
+ if (strcmpW(action,szLaunchConditions)==0)
+ rc = ACTION_LaunchConditions(package);
+ else if (strcmpW(action,szCostInitialize)==0)
+ rc = ACTION_CostInitialize(package);
+ else if (strcmpW(action,szFileCost)==0)
+ rc = ACTION_FileCost(package);
+ else if (strcmpW(action,szCostFinalize)==0)
+ rc = ACTION_CostFinalize(package);
+ else if (strcmpW(action,szInstallValidate)==0)
+ rc = ACTION_InstallValidate(package);
+
+ /* install block */
+ else if (strcmpW(action,szProcessComponents)==0)
+ rc = ACTION_ProcessComponents(package);
+ else if (strcmpW(action,szInstallInitialize)==0)
+ rc = ACTION_InstallInitialize(package);
+ else if (strcmpW(action,szCreateFolders)==0)
+ rc = ACTION_CreateFolders(package);
+ else if (strcmpW(action,szInstallFiles)==0)
+ rc = ACTION_InstallFiles(package);
+ else if (strcmpW(action,szDuplicateFiles)==0)
+ rc = ACTION_DuplicateFiles(package);
+ else if (strcmpW(action,szWriteRegistryValues)==0)
+ rc = ACTION_WriteRegistryValues(package);
+ else if (strcmpW(action,szRegisterTypeLibraries)==0)
+ rc = ACTION_RegisterTypeLibraries(package);
+ else if (strcmpW(action,szRegisterClassInfo)==0)
+ rc = ACTION_RegisterClassInfo(package);
+ else if (strcmpW(action,szRegisterProgIdInfo)==0)
+ rc = ACTION_RegisterProgIdInfo(package);
+ else if (strcmpW(action,szCreateShortcuts)==0)
+ rc = ACTION_CreateShortcuts(package);
+ else if (strcmpW(action,szPublishProduct)==0)
+ rc = ACTION_PublishProduct(package);
+
+ /*
+ Called during iTunes but unimplemented and seem important
+
+ ResolveSource (sets SourceDir)
+ RegisterProduct
+ InstallFinalize
+ */
+ else if ((rc = ACTION_CustomAction(package,action)) != ERROR_SUCCESS)
+ {
+ FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
+ rc = ERROR_FUNCTION_NOT_CALLED;
+ }
+
+ ui_actioninfo(package, action, FALSE, rc);
+ return rc;
+}
+
+
+static UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action)
+{
+ UINT rc = ERROR_SUCCESS;
+ MSIQUERY * view;
+ MSIRECORD * row = 0;
+ WCHAR ExecSeqQuery[1024] =
+ {'s','e','l','e','c','t',' ','*',' ','f','r','o','m',' ','C','u','s','t','o'
+,'m','A','c','t','i','o','n',' ','w','h','e','r','e',' ','`','A','c','t','i'
+,'o','n','`',' ','=',' ','`',0};
+ static const WCHAR end[]={'`',0};
+ UINT type;
+ LPWSTR source;
+ LPWSTR target;
+ WCHAR *deformated=NULL;
+
+ strcatW(ExecSeqQuery,action);
+ strcatW(ExecSeqQuery,end);
+
+ rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
+ rc = MSI_ViewExecute(view, 0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return rc;
+ }
+
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return rc;
+ }
+
[truncated at 1000 lines; 3881 more skipped]
reactos/lib/msi
diff -N cond.tab.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cond.tab.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,2022 @@
+/* A Bison parser, made from ./cond.y
+ by GNU bison 1.35. */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define yyparse COND_parse
+#define yylex COND_lex
+#define yyerror COND_error
+#define yylval COND_lval
+#define yychar COND_char
+#define yydebug COND_debug
+#define yynerrs COND_nerrs
+# define COND_SPACE 257
+# define COND_EOF 258
+# define COND_OR 259
+# define COND_AND 260
+# define COND_NOT 261
+# define COND_LT 262
+# define COND_GT 263
+# define COND_EQ 264
+# define COND_LPAR 265
+# define COND_RPAR 266
+# define COND_TILDA 267
+# define COND_PERCENT 268
+# define COND_DOLLARS 269
+# define COND_QUESTION 270
+# define COND_AMPER 271
+# define COND_EXCLAM 272
+# define COND_IDENT 273
+# define COND_NUMBER 274
+# define COND_LITER 275
+# define COND_ERROR 276
+
+#line 1 "./cond.y"
+
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2003 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+static int COND_error(char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_yyinput
+{
+ MSIPACKAGE *package;
+ LPCWSTR str;
+ INT n;
+ MSICONDITION result;
+} COND_input;
+
+struct cond_str {
+ LPCWSTR data;
+ INT len;
+};
+
+static LPWSTR COND_GetString( struct cond_str *str );
+static LPWSTR COND_GetLiteral( struct cond_str *str );
+static int COND_lex( void *COND_lval, COND_input *info);
+
+typedef INT (*comp_int)(INT a, INT b);
+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
+typedef INT (*comp_m1)(LPWSTR a,int b);
+typedef INT (*comp_m2)(int a,LPWSTR b);
+
+static INT comp_lt_i(INT a, INT b);
+static INT comp_gt_i(INT a, INT b);
+static INT comp_le_i(INT a, INT b);
+static INT comp_ge_i(INT a, INT b);
+static INT comp_eq_i(INT a, INT b);
+static INT comp_ne_i(INT a, INT b);
+static INT comp_bitand(INT a, INT b);
+static INT comp_highcomp(INT a, INT b);
+static INT comp_lowcomp(INT a, INT b);
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);
+
+static INT comp_eq_m1(LPWSTR a, INT b);
+static INT comp_ne_m1(LPWSTR a, INT b);
+static INT comp_lt_m1(LPWSTR a, INT b);
+static INT comp_gt_m1(LPWSTR a, INT b);
+static INT comp_le_m1(LPWSTR a, INT b);
+static INT comp_ge_m1(LPWSTR a, INT b);
+
+static INT comp_eq_m2(INT a, LPWSTR b);
+static INT comp_ne_m2(INT a, LPWSTR b);
+static INT comp_lt_m2(INT a, LPWSTR b);
+static INT comp_gt_m2(INT a, LPWSTR b);
+static INT comp_le_m2(INT a, LPWSTR b);
+static INT comp_ge_m2(INT a, LPWSTR b);
+
+
+#line 105 "./cond.y"
+#ifndef YYSTYPE
+typedef union
+{
+ struct cond_str str;
+ LPWSTR string;
+ INT value;
+ comp_int fn_comp_int;
+ comp_str fn_comp_str;
+ comp_m1 fn_comp_m1;
+ comp_m2 fn_comp_m2;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+
+
+#define YYFINAL 74
+#define YYFLAG -32768
+#define YYNTBASE 23
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 276 ? yytranslate[x] : 39)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+ 0, 0, 2, 4, 8, 10, 14, 16, 19, 21,
+ 23, 27, 31, 36, 40, 44, 48, 50, 53, 55,
+ 57, 60, 63, 66, 69, 72, 74, 77, 79, 81,
+ 84, 87, 90, 93, 96, 98, 101, 103, 105, 108,
+ 111, 114, 117, 120, 122, 125, 127, 129, 132, 135,
+ 138, 141, 144, 146, 148, 150, 152, 154, 157, 160,
+ 163, 166, 168, 171, 173
+};
+static const short yyrhs[] =
+{
+ 24, 0, 25, 0, 25, 5, 24, 0, 26, 0,
+ 25, 6, 26, 0, 27, 0, 7, 27, 0, 32,
+ 0, 33, 0, 32, 28, 32, 0, 33, 29, 33,
+ 0, 33, 13, 29, 33, 0, 33, 30, 32, 0,
+ 32, 31, 33, 0, 11, 24, 12, 0, 10, 0,
+ 8, 9, 0, 8, 0, 9, 0, 8, 10, 0,
+ 9, 10, 0, 9, 8, 0, 8, 8, 0, 9,
+ 9, 0, 10, 0, 8, 9, 0, 8, 0, 9,
+ 0, 8, 10, 0, 9, 10, 0, 9, 8, 0,
+ 8, 8, 0, 9, 9, 0, 10, 0, 8, 9,
+ 0, 8, 0, 9, 0, 8, 10, 0, 9, 10,
+ 0, 9, 8, 0, 8, 8, 0, 9, 9, 0,
+ 10, 0, 8, 9, 0, 8, 0, 9, 0, 8,
+ 10, 0, 9, 10, 0, 9, 8, 0, 8, 8,
+ 0, 9, 9, 0, 35, 0, 38, 0, 36, 0,
+ 34, 0, 21, 0, 15, 37, 0, 16, 37, 0,
+ 17, 37, 0, 18, 37, 0, 37, 0, 14, 37,
+ 0, 19, 0, 20, 0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+ 0, 135, 143, 148, 154, 159, 165, 170, 177, 182,
+ 186, 190, 194, 198, 202, 206, 212, 218, 222, 226,
+ 230, 234, 239, 243, 247, 253, 259, 263, 267, 271,
+ 275, 280, 284, 288, 294, 300, 304, 308, 312, 316,
+ 321, 325, 329, 335, 341, 345, 349, 353, 357, 362,
+ 366, 370, 376, 381, 387, 392, 398, 407, 417, 426,
+ 435, 446, 462, 475, 484
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+ "$", "error", "$undefined.", "COND_SPACE", "COND_EOF", "COND_OR",
+ "COND_AND", "COND_NOT", "COND_LT", "COND_GT", "COND_EQ", "COND_LPAR",
+ "COND_RPAR", "COND_TILDA", "COND_PERCENT", "COND_DOLLARS",
+ "COND_QUESTION", "COND_AMPER", "COND_EXCLAM", "COND_IDENT",
+ "COND_NUMBER", "COND_LITER", "COND_ERROR", "condition", "expression",
+ "boolean_term", "boolean_factor", "term", "comp_op_i", "comp_op_s",
+ "comp_op_m1", "comp_op_m2", "value_i", "value_s", "literal", "symbol_i",
+ "symbol_s", "identifier", "integer", 0
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+ 0, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 27, 27, 27, 27, 27, 27, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 32, 33, 33, 34, 35, 35, 35,
+ 35, 36, 36, 37, 38
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+ 0, 1, 1, 3, 1, 3, 1, 2, 1, 1,
+ 3, 3, 4, 3, 3, 3, 1, 2, 1, 1,
+ 2, 2, 2, 2, 2, 1, 2, 1, 1, 2,
+ 2, 2, 2, 2, 1, 2, 1, 1, 2, 2,
+ 2, 2, 2, 1, 2, 1, 1, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 1, 2, 1, 1
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+ doesn't specify something else to do. Zero means the default is an
+ error. */
+static const short yydefact[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 63, 64,
+ 56, 1, 2, 4, 6, 8, 9, 55, 52, 54,
+ 61, 53, 7, 0, 62, 57, 58, 59, 60, 0,
+ 0, 18, 19, 16, 0, 0, 36, 37, 34, 0,
+ 0, 0, 15, 3, 5, 23, 17, 20, 22, 24,
+ 21, 10, 14, 41, 35, 38, 40, 42, 39, 27,
+ 28, 25, 0, 11, 13, 32, 26, 29, 31, 33,
+ 30, 12, 0, 0, 0
+};
+
+static const short yydefgoto[] =
+{
+ 72, 11, 12, 13, 14, 34, 40, 41, 35, 15,
+ 16, 17, 18, 19, 20, 21
+};
+
+static const short yypact[] =
+{
+ -5, 50, -5, -12, -12, -12, -12, -12,-32768,-32768,
+ -32768,-32768, -2,-32768,-32768, 48, 123,-32768,-32768,-32768,
+ -32768,-32768,-32768, -4,-32768,-32768,-32768,-32768,-32768, -5,
+ -5, 10, 24, 33, 110, 58, 27, 41, 59, 135,
+ 58, 110,-32768,-32768,-32768, 62, 68, 71, 72, 80,
+ 81,-32768,-32768, 84, 90, 93, 94, 102, 103, 138,
+ 141,-32768, 58,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
+ -32768,-32768, 17, 21,-32768
+};
+
+static const short yypgoto[] =
+{
+ -32768, -1,-32768, -8, 25,-32768, -14,-32768,-32768, -11,
+ -35,-32768,-32768,-32768, 134,-32768
+};
+
+
+#define YYLAST 151
+
+
+static const short yytable[] =
+{
+ 52, 23, 1, 29, 30, 63, 2, 8, 42, 3,
+ 4, 5, 6, 7, 8, 9, 10, 73, 45, 46,
+ 47, 74, 44, 51, -45, 62, 22, 71, 43, -45,
+ 64, -45, 48, 49, 50, 53, 54, 55, -46, 0,
+ 0, -27, 0, -46, 0, -46, -27, -43, -27, 56,
+ 57, 58, -43, 0, -43, -28, 31, 32, 33, 0,
+ -28, 2, -28, 0, 3, 4, 5, 6, 7, 8,
+ 9, 10, 3, -25, 0, 0, -50, 8, -25, 10,
+ -25, -50, -44, -50, 0, -47, -49, -44, 0, -44,
+ -47, -49, -47, -49, -51, -48, 0, 0, -32, -51,
+ -48, -51, -48, -32, -26, -32, 0, -29, -31, -26,
+ 0, -26, -29, -31, -29, -31, -33, -30, 0, 0,
+ 0, -33, -30, -33, -30, 4, 5, 6, 7, 0,
+ 9, 36, 37, 38, 0, 0, 39, 24, 25, 26,
+ 27, 28, 0, 59, 60, 61, 65, 66, 67, 68,
+ 69, 70
+};
+
+static const short yycheck[] =
+{
+ 35, 2, 7, 5, 6, 40, 11, 19, 12, 14,
+ 15, 16, 17, 18, 19, 20, 21, 0, 8, 9,
+ 10, 0, 30, 34, 14, 39, 1, 62, 29, 19,
+ 41, 21, 8, 9, 10, 8, 9, 10, 14, -1,
+ -1, 14, -1, 19, -1, 21, 19, 14, 21, 8,
+ 9, 10, 19, -1, 21, 14, 8, 9, 10, -1,
+ 19, 11, 21, -1, 14, 15, 16, 17, 18, 19,
+ 20, 21, 14, 14, -1, -1, 14, 19, 19, 21,
+ 21, 19, 14, 21, -1, 14, 14, 19, -1, 21,
+ 19, 19, 21, 21, 14, 14, -1, -1, 14, 19,
+ 19, 21, 21, 19, 14, 21, -1, 14, 14, 19,
+ -1, 21, 19, 19, 21, 21, 14, 14, -1, -1,
+ -1, 19, 19, 21, 21, 15, 16, 17, 18, -1,
+ 20, 8, 9, 10, -1, -1, 13, 3, 4, 5,
+ 6, 7, -1, 8, 9, 10, 8, 9, 10, 8,
+ 9, 10
+};
+#define YYPURE 1
+
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* This is the parser code that is written into each bison parser when
+ the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+# if YYLSP_NEEDED
+ YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# if YYLSP_NEEDED
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAX)
+# else
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run).
+
+ When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+ first token. By default, to implement support for ranges, extend
+ its range to the last symbol. */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#if YYPURE
+# if YYLSP_NEEDED
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval, &yylloc)
+# endif
+# else /* !YYLSP_NEEDED */
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval)
+# endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX yylex ()
+#endif /* !YYPURE */
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+#endif
+
+#line 315 "/usr/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+ variables are global, or local to YYPARSE. */
+
+#define YY_DECL_NON_LSP_VARIABLES \
+/* The lookahead symbol. */ \
+int yychar; \
+ \
+/* The semantic value of the lookahead symbol. */ \
+YYSTYPE yylval; \
+ \
+/* Number of parse errors so far. */ \
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES \
+ \
+/* Location data for the lookahead symbol. */ \
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ /* If reentrant, generate the variables here. */
+#if YYPURE
+ YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+#if YYLSP_NEEDED
+ YYLTYPE yyloc;
+#endif
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+#if YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. */
+# if YYLSP_NEEDED
+ YYLTYPE *yyls1 = yyls;
+ /* This used to be a conditional around just the two extra args,
+ but that might be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+ yyls = yyls1;
+# else
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+# endif
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (yystacksize >= YYMAXDEPTH)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (yystacksize > YYMAXDEPTH)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+# if YYLSP_NEEDED
+ YYSTACK_RELOCATE (yyls);
+# endif
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+#if YYLSP_NEEDED
+ yylsp = yyls + yysize - 1;
+#endif
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyssp >= yyss + yystacksize - 1)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYFLAG)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* yychar is either YYEMPTY or YYEOF
+ or a valid token in external form. */
+
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ /* Convert token to internal form (in yychar1) for indexing tables with */
+
+ if (yychar <= 0) /* This means end of input. */
+ {
+ yychar1 = 0;
+ yychar = YYEOF; /* Don't call YYLEX any more */
+
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yychar1 = YYTRANSLATE (yychar);
+
+#if YYDEBUG
+ /* We have to keep this `#if YYDEBUG', since we use variables
+ which are defined only if `YYDEBUG' is set. */
+ if (yydebug)
+ {
+ YYFPRINTF (stderr, "Next token is %d (%s",
+ yychar, yytname[yychar1]);
+ /* Give the individual parser a way to print the precise
+ meaning of a token, for further debugging info. */
+# ifdef YYPRINT
+ YYPRINT (stderr, yychar, yylval);
+# endif
+ YYFPRINTF (stderr, ")\n");
+ }
+#endif
+ }
+
+ yyn += yychar1;
+ if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
+ goto yydefault;
+
+ yyn = yytable[yyn];
+
+ /* yyn is what to do for this token type in this state.
+ Negative => reduce, -yyn is rule number.
+ Positive => shift, yyn is new state.
+ New state is final state => don't bother to shift,
+ just return success.
+ 0, or most negative number => error. */
+
+ if (yyn < 0)
+ {
+ if (yyn == YYFLAG)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
[truncated at 1000 lines; 1026 more skipped]
reactos/lib/msi
diff -N cond.tab.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cond.tab.h 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,40 @@
+#ifndef BISON_COND_TAB_H
+# define BISON_COND_TAB_H
+
+#ifndef YYSTYPE
+typedef union
+{
+ struct cond_str str;
+ LPWSTR string;
+ INT value;
+ comp_int fn_comp_int;
+ comp_str fn_comp_str;
+ comp_m1 fn_comp_m1;
+ comp_m2 fn_comp_m2;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define COND_SPACE 257
+# define COND_EOF 258
+# define COND_OR 259
+# define COND_AND 260
+# define COND_NOT 261
+# define COND_LT 262
+# define COND_GT 263
+# define COND_EQ 264
+# define COND_LPAR 265
+# define COND_RPAR 266
+# define COND_TILDA 267
+# define COND_PERCENT 268
+# define COND_DOLLARS 269
+# define COND_QUESTION 270
+# define COND_AMPER 271
+# define COND_EXCLAM 272
+# define COND_IDENT 273
+# define COND_NUMBER 274
+# define COND_LITER 275
+# define COND_ERROR 276
+
+
+#endif /* not BISON_COND_TAB_H */
reactos/lib/msi
diff -N cond.y
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cond.y 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,774 @@
+%{
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2003 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+static int COND_error(char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_yyinput
+{
+ MSIPACKAGE *package;
+ LPCWSTR str;
+ INT n;
+ MSICONDITION result;
+} COND_input;
+
+struct cond_str {
+ LPCWSTR data;
+ INT len;
+};
+
+static LPWSTR COND_GetString( struct cond_str *str );
+static LPWSTR COND_GetLiteral( struct cond_str *str );
+static int COND_lex( void *COND_lval, COND_input *info);
+
+typedef INT (*comp_int)(INT a, INT b);
+typedef INT (*comp_str)(LPWSTR a, LPWSTR b, BOOL caseless);
+typedef INT (*comp_m1)(LPWSTR a,int b);
+typedef INT (*comp_m2)(int a,LPWSTR b);
+
+static INT comp_lt_i(INT a, INT b);
+static INT comp_gt_i(INT a, INT b);
+static INT comp_le_i(INT a, INT b);
+static INT comp_ge_i(INT a, INT b);
+static INT comp_eq_i(INT a, INT b);
+static INT comp_ne_i(INT a, INT b);
+static INT comp_bitand(INT a, INT b);
+static INT comp_highcomp(INT a, INT b);
+static INT comp_lowcomp(INT a, INT b);
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless);
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless);
+
+static INT comp_eq_m1(LPWSTR a, INT b);
+static INT comp_ne_m1(LPWSTR a, INT b);
+static INT comp_lt_m1(LPWSTR a, INT b);
+static INT comp_gt_m1(LPWSTR a, INT b);
+static INT comp_le_m1(LPWSTR a, INT b);
+static INT comp_ge_m1(LPWSTR a, INT b);
+
+static INT comp_eq_m2(INT a, LPWSTR b);
+static INT comp_ne_m2(INT a, LPWSTR b);
+static INT comp_lt_m2(INT a, LPWSTR b);
+static INT comp_gt_m2(INT a, LPWSTR b);
+static INT comp_le_m2(INT a, LPWSTR b);
+static INT comp_ge_m2(INT a, LPWSTR b);
+
+%}
+
+%pure-parser
+
+%union
+{
+ struct cond_str str;
+ LPWSTR string;
+ INT value;
+ comp_int fn_comp_int;
+ comp_str fn_comp_str;
+ comp_m1 fn_comp_m1;
+ comp_m2 fn_comp_m2;
+}
+
+%token COND_SPACE COND_EOF COND_SPACE
+%token COND_OR COND_AND COND_NOT
+%token COND_LT COND_GT COND_EQ
+%token COND_LPAR COND_RPAR COND_TILDA
+%token COND_PERCENT COND_DOLLARS COND_QUESTION COND_AMPER COND_EXCLAM
+%token <str> COND_IDENT <str> COND_NUMBER <str> COND_LITER
+
+%nonassoc COND_EOF COND_ERROR
+
+%type <value> expression boolean_term boolean_factor
+%type <value> term value_i symbol_i integer
+%type <string> identifier value_s symbol_s literal
+%type <fn_comp_int> comp_op_i
+%type <fn_comp_str> comp_op_s
+%type <fn_comp_m1> comp_op_m1
+%type <fn_comp_m2> comp_op_m2
+
+%%
+
+condition:
+ expression
+ {
+ COND_input* cond = (COND_input*) info;
+ cond->result = $1;
+ }
+ ;
+
+expression:
+ boolean_term
+ {
+ $$ = $1;
+ }
+ | boolean_term COND_OR expression
+ {
+ $$ = $1 || $3;
+ }
+ ;
+
+boolean_term:
+ boolean_factor
+ {
+ $$ = $1;
+ }
+ | boolean_term COND_AND boolean_factor
+ {
+ $$ = $1 && $3;
+ }
+ ;
+
+boolean_factor:
+ term
+ {
+ $$ = $1;
+ }
+ | COND_NOT term
+ {
+ $$ = ! $2;
+ }
+ ;
+
+
+term:
+ value_i
+ {
+ $$ = $1;
+ }
+ | value_s
+ {
+ $$ = atoiW($1);
+ }
+ | value_i comp_op_i value_i
+ {
+ $$ = $2( $1, $3 );
+ }
+ | value_s comp_op_s value_s
+ {
+ $$ = $2( $1, $3, FALSE );
+ }
+ | value_s COND_TILDA comp_op_s value_s
+ {
+ $$ = $3( $1, $4, TRUE );
+ }
+ | value_s comp_op_m1 value_i
+ {
+ $$ = $2( $1, $3 );
+ }
+ | value_i comp_op_m2 value_s
+ {
+ $$ = $2( $1, $3 );
+ }
+ | COND_LPAR expression COND_RPAR
+ {
+ $$ = $2;
+ }
+ ;
+
+comp_op_i:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_i;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_i;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_i;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_i;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_i;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_i;
+ }
+ /*Int only*/
+ | COND_GT COND_LT
+ {
+ $$ = comp_bitand;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = comp_highcomp;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = comp_lowcomp;
+ }
+ ;
+
+comp_op_s:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_s;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_s;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_s;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_s;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_s;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_s;
+ }
+ /*string only*/
+ | COND_GT COND_LT
+ {
+ $$ = comp_substring;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = comp_start;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = comp_end;
+ }
+ ;
+
+comp_op_m1:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_m1;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_m1;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_m1;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_m1;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_m1;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_m1;
+ }
+ /*Not valid for mixed compares*/
+ | COND_GT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = 0;
+ }
+ ;
+
+comp_op_m2:
+ /* common functions */
+ COND_EQ
+ {
+ $$ = comp_eq_m2;
+ }
+ | COND_LT COND_GT
+ {
+ $$ = comp_ne_m2;
+ }
+ | COND_LT
+ {
+ $$ = comp_lt_m2;
+ }
+ | COND_GT
+ {
+ $$ = comp_gt_m2;
+ }
+ | COND_LT COND_EQ
+ {
+ $$ = comp_le_m2;
+ }
+ | COND_GT COND_EQ
+ {
+ $$ = comp_ge_m2;
+ }
+ /*Not valid for mixed compares*/
+ | COND_GT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_LT COND_LT
+ {
+ $$ = 0;
+ }
+ | COND_GT COND_GT
+ {
+ $$ = 0;
+ }
+ ;
+
+value_i:
+ symbol_i
+ {
+ $$ = $1;
+ }
+ | integer
+ {
+ $$ = $1;
+ }
+ ;
+
+value_s:
+ symbol_s
+ {
+ $$ = $1;
+ }
+ | literal
+ {
+ $$ = $1;
+ }
+ ;
+
+literal:
+ COND_LITER
+ {
+ $$ = COND_GetLiteral(&$1);
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+symbol_i:
+ COND_DOLLARS identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetComponentStateW(cond->package, $2, &install, &action );
+ $$ = action;
+ HeapFree( GetProcessHeap(), 0, $2 );
+ }
+ | COND_QUESTION identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetComponentStateW(cond->package, $2, &install, &action );
+ $$ = install;
+ HeapFree( GetProcessHeap(), 0, $2 );
+ }
+ | COND_AMPER identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetFeatureStateW(cond->package, $2, &install, &action );
+ $$ = action;
+ HeapFree( GetProcessHeap(), 0, $2 );
+ }
+ | COND_EXCLAM identifier
+ {
+ COND_input* cond = (COND_input*) info;
+ INSTALLSTATE install = INSTALLSTATE_UNKNOWN, action = INSTALLSTATE_UNKNOWN;
+
+ MSI_GetFeatureStateW(cond->package, $2, &install, &action );
+ $$ = install;
+ HeapFree( GetProcessHeap(), 0, $2 );
+ }
+ ;
+
+symbol_s:
+ identifier
+ {
+ DWORD sz;
+ COND_input* cond = (COND_input*) info;
+ $$ = HeapAlloc( GetProcessHeap(), 0, 0x100*sizeof (WCHAR) );
+
+ /* Lookup the identifier */
+
+ sz=0x100;
+ if (MSI_GetPropertyW(cond->package,$1,$$,&sz) != ERROR_SUCCESS)
+ {
+ $$[0]=0;
+ }
+ HeapFree( GetProcessHeap(), 0, $1 );
+ }
+ | COND_PERCENT identifier
+ {
+ UINT len = GetEnvironmentVariableW( $2, NULL, 0 );
+ if( len++ )
+ {
+ $$ = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+ if( $$ )
+ GetEnvironmentVariableW( $2, $$, len );
+ }
+ HeapFree( GetProcessHeap(), 0, $2 );
+ }
+ ;
+
+identifier:
+ COND_IDENT
+ {
+ $$ = COND_GetString(&$1);
+ if( !$$ )
+ YYABORT;
+ }
+ ;
+
+integer:
+ COND_NUMBER
+ {
+ LPWSTR szNum = COND_GetString(&$1);
+ if( !szNum )
+ YYABORT;
+ $$ = atoiW( szNum );
+ HeapFree( GetProcessHeap(), 0, szNum );
+ }
+ ;
+
+%%
+
+
+static int COND_IsAlpha( WCHAR x )
+{
+ return( ( ( x >= 'A' ) && ( x <= 'Z' ) ) ||
+ ( ( x >= 'a' ) && ( x <= 'z' ) ) ||
+ ( ( x == '_' ) ) );
+}
+
+static int COND_IsNumber( WCHAR x )
+{
+ return( (( x >= '0' ) && ( x <= '9' )) || (x =='-') || (x =='.') );
+}
+
+
+/* the mess of comparison functions */
+
+static INT comp_lt_i(INT a, INT b)
+{ return (a < b); }
+static INT comp_gt_i(INT a, INT b)
+{ return (a > b); }
+static INT comp_le_i(INT a, INT b)
+{ return (a <= b); }
+static INT comp_ge_i(INT a, INT b)
+{ return (a >= b); }
+static INT comp_eq_i(INT a, INT b)
+{ return (a == b); }
+static INT comp_ne_i(INT a, INT b)
+{ return (a != b); }
+static INT comp_bitand(INT a, INT b)
+{ return a & b;}
+static INT comp_highcomp(INT a, INT b)
+{ return HIWORD(a)==b; }
+static INT comp_lowcomp(INT a, INT b)
+{ return LOWORD(a)==b; }
+
+static INT comp_eq_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return !strcmpiW(a,b); else return !strcmpW(a,b);}
+static INT comp_ne_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b); else return strcmpW(a,b);}
+static INT comp_lt_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)<0; else return strcmpW(a,b)<0;}
+static INT comp_gt_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)>0; else return strcmpW(a,b)>0;}
+static INT comp_le_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)<=0; else return strcmpW(a,b)<=0;}
+static INT comp_ge_s(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strcmpiW(a,b)>=0; else return strcmpW(a,b)>=0;}
+static INT comp_substring(LPWSTR a, LPWSTR b, BOOL casless)
+/* ERROR NOT WORKING REWRITE */
+{ if (casless) return strstrW(a,b)!=NULL; else return strstrW(a,b)!=NULL;}
+static INT comp_start(LPWSTR a, LPWSTR b, BOOL casless)
+{ if (casless) return strncmpiW(a,b,strlenW(b))==0;
+ else return strncmpW(a,b,strlenW(b))==0;}
+static INT comp_end(LPWSTR a, LPWSTR b, BOOL casless)
+{
+ int i = strlenW(a);
+ int j = strlenW(b);
+ if (j>i)
+ return 0;
+ if (casless) return (!strcmpiW(&a[i-j-1],b));
+ else return (!strcmpW(&a[i-j-1],b));
+}
+
+
+static INT comp_eq_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)==b; else return 0;}
+static INT comp_ne_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)!=b; else return 1;}
+static INT comp_lt_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)<b; else return 0;}
+static INT comp_gt_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)>b; else return 0;}
+static INT comp_le_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)<=b; else return 0;}
+static INT comp_ge_m1(LPWSTR a, INT b)
+{ if (COND_IsNumber(a[0])) return atoiW(a)>=b; else return 0;}
+
+static INT comp_eq_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a == atoiW(b); else return 0;}
+static INT comp_ne_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a != atoiW(b); else return 1;}
+static INT comp_lt_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a < atoiW(b); else return 0;}
+static INT comp_gt_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a > atoiW(b); else return 0;}
+static INT comp_le_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a <= atoiW(b); else return 0;}
+static INT comp_ge_m2(INT a, LPWSTR b)
+{ if (COND_IsNumber(b[0])) return a >= atoiW(b); else return 0;}
+
+
+
+static int COND_IsIdent( WCHAR x )
+{
+ return( COND_IsAlpha( x ) || COND_IsNumber( x ) || ( x == '_' )
+ || ( x == '#' ) || (x == '.') );
+}
+
+static int COND_GetOne( struct cond_str *str, COND_input *cond )
+{
+ static const WCHAR szNot[] = {'N','O','T',0};
+ static const WCHAR szAnd[] = {'A','N','D',0};
+ static const WCHAR szOr[] = {'O','R',0};
+ WCHAR ch;
+ int rc, len = 1;
+
+ str->data = &cond->str[cond->n];
+
+ ch = str->data[0];
+ switch( ch )
+ {
+ case 0: return 0;
+ case '(': rc = COND_LPAR; break;
+ case ')': rc = COND_RPAR; break;
+ case '&': rc = COND_AMPER; break;
+ case '!': rc = COND_EXCLAM; break;
+ case '$': rc = COND_DOLLARS; break;
+ case '?': rc = COND_QUESTION; break;
+ case '%': rc = COND_PERCENT; break;
+ case ' ': rc = COND_SPACE; break;
+ case '=': rc = COND_EQ; break;
+ case '~': rc = COND_TILDA; break;
+ case '<': rc = COND_LT; break;
+ case '>': rc = COND_GT; break;
+ case '"':
+ {
+ const WCHAR *ch2 = str->data + 1;
+
+
+ while ( *ch2 && *ch2 != '"' )
+ ++ch2;
+ if (*ch2 == '"')
+ {
+ len = ch2 - str->data + 1;
+ rc = COND_LITER;
+ break;
+ }
+ }
+ ERR("Unterminated string\n");
+ rc = COND_ERROR;
+ break;
+ default:
+ if( COND_IsAlpha( ch ) )
+ {
+ while( COND_IsIdent( str->data[len] ) )
+ len++;
+ rc = COND_IDENT;
+ break;
+ }
+
+ if( COND_IsNumber( ch ) )
+ {
+ while( COND_IsNumber( str->data[len] ) )
+ len++;
+ rc = COND_NUMBER;
+ break;
+ }
+
+ ERR("Got unknown character %c(%x)\n",ch,ch);
+ rc = COND_ERROR;
+ break;
+ }
+
+ /* keyword identifiers */
+ if( rc == COND_IDENT )
+ {
+ if( (len==3) && (strncmpiW(str->data,szNot,len)==0) )
+ rc = COND_NOT;
+ else if( (len==3) && (strncmpiW(str->data,szAnd,len)==0) )
+ rc = COND_AND;
+ else if( (len==2) && (strncmpiW(str->data,szOr,len)==0) )
+ rc = COND_OR;
+ }
+
+ cond->n += len;
+ str->len = len;
+
+ return rc;
+}
+
+static int COND_lex( void *COND_lval, COND_input *cond )
+{
+ int rc;
+ struct cond_str *str = COND_lval;
+
+ do {
+ rc = COND_GetOne( str, cond );
+ } while (rc == COND_SPACE);
+
+ return rc;
+}
+
+static LPWSTR COND_GetString( struct cond_str *str )
+{
+ LPWSTR ret;
+
+ ret = HeapAlloc( GetProcessHeap(), 0, (str->len+1) * sizeof (WCHAR) );
+ if( ret )
+ {
+ strncpyW( ret, str->data, str->len );
+ ret[str->len]=0;
+ }
+ TRACE("Got identifier %s\n",debugstr_w(ret));
+ return ret;
+}
+
+static LPWSTR COND_GetLiteral( struct cond_str *str )
+{
+ LPWSTR ret;
+
+ ret = HeapAlloc( GetProcessHeap(), 0, (str->len-1) * sizeof (WCHAR) );
+ if( ret )
+ {
+ memcpy( ret, str->data+1, (str->len-2) * sizeof(WCHAR) );
+ ret[str->len - 2]=0;
+ }
+ TRACE("Got literal %s\n",debugstr_w(ret));
+ return ret;
+}
+
+static int COND_error(char *str)
+{
+ return 0;
+}
+
+MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *package, LPCWSTR szCondition )
+{
+ COND_input cond;
+ MSICONDITION r;
+
+ cond.package = package;
+ cond.str = szCondition;
+ cond.n = 0;
+ cond.result = -1;
+
+ TRACE("Evaluating %s\n",debugstr_w(szCondition));
+
+ if( !COND_parse( &cond ) )
+ r = cond.result;
+ else
+ r = MSICONDITION_ERROR;
+
+ TRACE("Evaluates to %i\n",r);
+ return r;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionW( MSIHANDLE hInstall, LPCWSTR szCondition )
+{
+ MSIPACKAGE *package;
+ UINT ret;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if( !package)
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_EvaluateConditionW( package, szCondition );
+ msiobj_release( &package->hdr );
+ return ret;
+}
+
+MSICONDITION WINAPI MsiEvaluateConditionA( MSIHANDLE hInstall, LPCSTR szCondition )
+{
+ LPWSTR szwCond = NULL;
+ MSICONDITION r;
+
+ if( szCondition )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szCondition, -1, NULL, 0 );
+ szwCond = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, szCondition, -1, szwCond, len );
+ }
+
+ r = MsiEvaluateConditionW( hInstall, szwCond );
+
+ if( szwCond )
+ HeapFree( GetProcessHeap(), 0, szwCond );
+
+ return r;
+}
reactos/lib/msi
diff -N create.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ create.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,258 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSICREATEVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ LPWSTR name;
+ BOOL bIsTemp;
+ create_col_info *col_info;
+} MSICREATEVIEW;
+
+static UINT CREATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+ TRACE("%p %d %d %p\n", cv, row, col, val );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+ create_col_info *col;
+ UINT r, nField, row, table_val, column_val;
+ static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
+ static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
+ MSIVIEW *tv = NULL;
+
+ TRACE("%p Table %s (%s)\n", cv, debugstr_w(cv->name),
+ cv->bIsTemp?"temporary":"permanent");
+
+ /* only add tables that don't exist already */
+ if( TABLE_Exists(cv->db, cv->name ) )
+ return ERROR_BAD_QUERY_SYNTAX;
+
+ /* add the name to the _Tables table */
+ table_val = msi_addstringW( cv->db->strings, 0, cv->name, -1, 1 );
+ TRACE("New string %s -> %d\n", debugstr_w( cv->name ), table_val );
+ if( table_val < 0 )
+ return ERROR_FUNCTION_FAILED;
+
+ r = TABLE_CreateView( cv->db, szTables, &tv );
+ TRACE("CreateView returned %x\n", r);
+ if( r )
+ return r;
+
+ r = tv->ops->execute( tv, 0 );
+ TRACE("tv execute returned %x\n", r);
+ if( r )
+ return r;
+
+ row = -1;
+ r = tv->ops->insert_row( tv, &row );
+ TRACE("insert_row returned %x\n", r);
+ if( r )
+ goto err;
+
+ r = tv->ops->set_int( tv, row, 1, table_val );
+ if( r )
+ goto err;
+ tv->ops->delete( tv );
+ tv = NULL;
+
+ /* add each column to the _Columns table */
+ r = TABLE_CreateView( cv->db, szColumns, &tv );
+ if( r )
+ return r;
+
+ r = tv->ops->execute( tv, 0 );
+ TRACE("tv execute returned %x\n", r);
+ if( r )
+ return r;
+
+ /*
+ * need to set the table, column number, col name and type
+ * for each column we enter in the table
+ */
+ nField = 1;
+ for( col = cv->col_info; col; col = col->next )
+ {
+ row = -1;
+ r = tv->ops->insert_row( tv, &row );
+ if( r )
+ goto err;
+
+ column_val = msi_addstringW( cv->db->strings, 0, col->colname, -1, 1 );
+ TRACE("New string %s -> %d\n", debugstr_w( col->colname ), column_val );
+ if( column_val < 0 )
+ break;
+
+ /* add the string again here so we increase the reference count */
+ table_val = msi_addstringW( cv->db->strings, 0, cv->name, -1, 1 );
+ if( table_val < 0 )
+ break;
+
+ r = tv->ops->set_int( tv, row, 1, table_val );
+ if( r )
+ break;
+
+ r = tv->ops->set_int( tv, row, 2, 0x8000|nField );
+ if( r )
+ break;
+
+ r = tv->ops->set_int( tv, row, 3, column_val );
+ if( r )
+ break;
+
+ r = tv->ops->set_int( tv, row, 4, 0x8000|col->type );
+ if( r )
+ break;
+
+ nField++;
+ }
+ if( !col )
+ r = ERROR_SUCCESS;
+
+err:
+ /* FIXME: remove values from the string table on error */
+ if( tv )
+ tv->ops->delete( tv );
+ return r;
+}
+
+static UINT CREATE_close( struct tagMSIVIEW *view )
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+ TRACE("%p\n", cv);
+
+ return ERROR_SUCCESS;
+}
+
+static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+ TRACE("%p %p %p\n", cv, rows, cols );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+ TRACE("%p %d %p %p\n", cv, n, name, type );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+
+ TRACE("%p %d %ld\n", cv, eModifyMode, hrec );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT CREATE_delete( struct tagMSIVIEW *view )
+{
+ MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
+ create_col_info *col;
+
+ TRACE("%p\n", cv );
+
+ col = cv->col_info;
+ while( col )
+ {
+ create_col_info *t = col;
+ col = col->next;
+ HeapFree( GetProcessHeap(), 0, t->colname );
+ HeapFree( GetProcessHeap(), 0, t );
+ }
+ msiobj_release( &cv->db->hdr );
+ HeapFree( GetProcessHeap(), 0, cv->name );
+ HeapFree( GetProcessHeap(), 0, cv );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS create_ops =
+{
+ CREATE_fetch_int,
+ NULL,
+ NULL,
+ NULL,
+ CREATE_execute,
+ CREATE_close,
+ CREATE_get_dimensions,
+ CREATE_get_column_info,
+ CREATE_modify,
+ CREATE_delete
+};
+
+UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+ create_col_info *col_info, BOOL temp )
+{
+ MSICREATEVIEW *cv = NULL;
+
+ TRACE("%p\n", cv );
+
+ cv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *cv );
+ if( !cv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ cv->view.ops = &create_ops;
+ msiobj_addref( &db->hdr );
+ cv->db = db;
+ cv->name = table; /* FIXME: strdupW it? */
+ cv->col_info = col_info;
+ cv->bIsTemp = temp;
+ *view = (MSIVIEW*) cv;
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N distinct.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ distinct.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,293 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tagDISTINCTSET
+{
+ UINT val;
+ UINT count;
+ UINT row;
+ struct tagDISTINCTSET *nextrow;
+ struct tagDISTINCTSET *nextcol;
+} DISTINCTSET;
+
+typedef struct tagMSIDISTINCTVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ MSIVIEW *table;
+ UINT row_count;
+ UINT *translation;
+} MSIDISTINCTVIEW;
+
+static DISTINCTSET ** distinct_insert( DISTINCTSET **x, UINT val, UINT row )
+{
+ /* horrible O(n) find */
+ while( *x )
+ {
+ if( (*x)->val == val )
+ {
+ (*x)->count++;
+ return x;
+ }
+ x = &(*x)->nextrow;
+ }
+
+ /* nothing found, so add one */
+ *x = HeapAlloc( GetProcessHeap(), 0, sizeof (DISTINCTSET) );
+ if( *x )
+ {
+ (*x)->val = val;
+ (*x)->count = 1;
+ (*x)->row = row;
+ (*x)->nextrow = NULL;
+ (*x)->nextcol = NULL;
+ }
+ return x;
+}
+
+static void distinct_free( DISTINCTSET *x )
+{
+ while( x )
+ {
+ DISTINCTSET *next = x->nextrow;
+ distinct_free( x->nextcol );
+ HeapFree( GetProcessHeap(), 0, x );
+ x = next;
+ }
+}
+
+static UINT DISTINCT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+ TRACE("%p %d %d %p\n", dv, row, col, val );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( row >= dv->row_count )
+ return ERROR_INVALID_PARAMETER;
+
+ row = dv->translation[ row ];
+
+ return dv->table->ops->fetch_int( dv->table, row, col, val );
+}
+
+static UINT DISTINCT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+ UINT r, i, j, r_count, c_count;
+ DISTINCTSET *rowset = NULL;
+
+ TRACE("%p %p\n", dv, record);
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ r = dv->table->ops->execute( dv->table, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = dv->table->ops->get_dimensions( dv->table, &r_count, &c_count );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ dv->translation = HeapAlloc( GetProcessHeap(), 0, r_count*sizeof(UINT) );
+ if( !dv->translation )
+ return ERROR_FUNCTION_FAILED;
+
+ /* build it */
+ for( i=0; i<r_count; i++ )
+ {
+ DISTINCTSET **x = &rowset;
+
+ for( j=1; j<=c_count; j++ )
+ {
+ UINT val = 0;
+ r = dv->table->ops->fetch_int( dv->table, i, j, &val );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("Failed to fetch int at %d %d\n", i, j );
+ distinct_free( rowset );
+ return r;
+ }
+ x = distinct_insert( x, val, i );
+ if( !*x )
+ {
+ ERR("Failed to insert at %d %d\n", i, j );
+ distinct_free( rowset );
+ return ERROR_FUNCTION_FAILED;
+ }
+ if( j != c_count )
+ x = &(*x)->nextcol;
+ }
+
+ /* check if it was distinct and if so, include it */
+ if( (*x)->row == i )
+ {
+ TRACE("Row %d -> %d\n", dv->row_count, i);
+ dv->translation[dv->row_count++] = i;
+ }
+ }
+
+ distinct_free( rowset );
+
+ return ERROR_SUCCESS;
+}
+
+static UINT DISTINCT_close( struct tagMSIVIEW *view )
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+ TRACE("%p\n", dv );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( dv->translation )
+ HeapFree( GetProcessHeap(), 0, dv->translation );
+ dv->translation = NULL;
+ dv->row_count = 0;
+
+ return dv->table->ops->close( dv->table );
+}
+
+static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+ TRACE("%p %p %p\n", dv, rows, cols );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( rows )
+ {
+ if( !dv->translation )
+ return ERROR_FUNCTION_FAILED;
+ *rows = dv->row_count;
+ }
+
+ return dv->table->ops->get_dimensions( dv->table, NULL, cols );
+}
+
+static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+ TRACE("%p %d %p %p\n", dv, n, name, type );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return dv->table->ops->get_column_info( dv->table, n, name, type );
+}
+
+static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+ TRACE("%p %d %ld\n", dv, eModifyMode, hrec );
+
+ if( !dv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return dv->table->ops->modify( dv->table, eModifyMode, hrec );
+}
+
+static UINT DISTINCT_delete( struct tagMSIVIEW *view )
+{
+ MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
+
+ TRACE("%p\n", dv );
+
+ if( dv->table )
+ dv->table->ops->delete( dv->table );
+
+ if( dv->translation )
+ HeapFree( GetProcessHeap(), 0, dv->translation );
+ msiobj_release( &dv->db->hdr );
+ HeapFree( GetProcessHeap(), 0, dv );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS distinct_ops =
+{
+ DISTINCT_fetch_int,
+ NULL,
+ NULL,
+ NULL,
+ DISTINCT_execute,
+ DISTINCT_close,
+ DISTINCT_get_dimensions,
+ DISTINCT_get_column_info,
+ DISTINCT_modify,
+ DISTINCT_delete
+};
+
+UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
+{
+ MSIDISTINCTVIEW *dv = NULL;
+ UINT count = 0, r;
+
+ TRACE("%p\n", dv );
+
+ r = table->ops->get_dimensions( table, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("can't get table dimensions\n");
+ return r;
+ }
+
+ dv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *dv );
+ if( !dv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ dv->view.ops = &distinct_ops;
+ msiobj_addref( &db->hdr );
+ dv->db = db;
+ dv->table = table;
+ dv->translation = NULL;
+ dv->row_count = 0;
+ *view = (MSIVIEW*) dv;
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N handle.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ handle.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,215 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+static CRITICAL_SECTION MSI_handle_cs;
+static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
+{
+ 0, 0, &MSI_handle_cs,
+ { &MSI_handle_cs_debug.ProcessLocksList,
+ &MSI_handle_cs_debug.ProcessLocksList },
+ 0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }
+};
+static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
+
+MSIOBJECTHDR *msihandletable[MSIMAXHANDLES];
+
+MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
+{
+ MSIHANDLE ret = 0;
+ UINT i;
+
+ EnterCriticalSection( &MSI_handle_cs );
+
+ /* find a slot */
+ for(i=0; i<MSIMAXHANDLES; i++)
+ if( !msihandletable[i] )
+ break;
+ if( (i>=MSIMAXHANDLES) || msihandletable[i] )
+ goto out;
+
+ msiobj_addref( obj );
+ msihandletable[i] = obj;
+ ret = (MSIHANDLE) (i+1);
+out:
+ TRACE("%p -> %ld\n", obj, ret );
+
+ LeaveCriticalSection( &MSI_handle_cs );
+ return ret;
+}
+
+void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
+{
+ MSIOBJECTHDR *ret = NULL;
+
+ EnterCriticalSection( &MSI_handle_cs );
+ handle--;
+ if( handle<0 )
+ goto out;
+ if( handle>=MSIMAXHANDLES )
+ goto out;
+ if( !msihandletable[handle] )
+ goto out;
+ if( msihandletable[handle]->magic != MSIHANDLE_MAGIC )
+ goto out;
+ if( type && (msihandletable[handle]->type != type) )
+ goto out;
+ ret = msihandletable[handle];
+ msiobj_addref( ret );
+
+out:
+ LeaveCriticalSection( &MSI_handle_cs );
+
+ return (void*) ret;
+}
+
+MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
+{
+ MSIHANDLE ret = 0;
+ UINT i;
+
+ TRACE("%p\n", hdr);
+
+ EnterCriticalSection( &MSI_handle_cs );
+ for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
+ if( msihandletable[i] == hdr )
+ ret = i+1;
+ LeaveCriticalSection( &MSI_handle_cs );
+
+ TRACE("%p -> %ld\n", hdr, ret);
+
+ msiobj_addref( hdr );
+ return ret;
+}
+
+void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
+{
+ MSIOBJECTHDR *info;
+
+ info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
+ if( info )
+ {
+ info->magic = MSIHANDLE_MAGIC;
+ info->type = type;
+ info->refcount = 1;
+ info->destructor = destroy;
+ }
+
+ return info;
+}
+
+void msiobj_addref( MSIOBJECTHDR *info )
+{
+ TRACE("%p\n", info);
+
+ if( !info )
+ return;
+
+ if( info->magic != MSIHANDLE_MAGIC )
+ {
+ ERR("Invalid handle!\n");
+ return;
+ }
+
+ info->refcount++;
+}
+
+int msiobj_release( MSIOBJECTHDR *info )
+{
+ int ret;
+
+ TRACE("%p\n",info);
+
+ if( !info )
+ return -1;
+
+ if( info->magic != MSIHANDLE_MAGIC )
+ {
+ ERR("Invalid handle!\n");
+ return -1;
+ }
+
+ ret = info->refcount--;
+ if (info->refcount == 0)
+ {
+ if( info->destructor )
+ info->destructor( info );
+ HeapFree( GetProcessHeap(), 0, info );
+ TRACE("object %p destroyed\n", info);
+ }
+
+ return ret;
+}
+
+UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
+{
+ MSIOBJECTHDR *info;
+ UINT ret = ERROR_INVALID_HANDLE;
+
+ TRACE("%lx\n",handle);
+
+ EnterCriticalSection( &MSI_handle_cs );
+
+ info = msihandle2msiinfo(handle, 0);
+ if( !info )
+ goto out;
+
+ if( info->magic != MSIHANDLE_MAGIC )
+ {
+ ERR("Invalid handle!\n");
+ goto out;
+ }
+
+ msiobj_release( info );
+ msihandletable[handle-1] = NULL;
+ ret = ERROR_SUCCESS;
+
+ TRACE("handle %lx Destroyed\n", handle);
+out:
+ LeaveCriticalSection( &MSI_handle_cs );
+ if( info )
+ msiobj_release( info );
+
+ return ret;
+}
+
+UINT WINAPI MsiCloseAllHandles(void)
+{
+ UINT i;
+
+ TRACE("\n");
+
+ for(i=0; i<MSIMAXHANDLES; i++)
+ MsiCloseHandle( i+1 );
+
+ return 0;
+}
reactos/lib/msi
diff -N insert.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ insert.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,238 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIINSERTVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ BOOL bIsTemp;
+ MSIVIEW *sv;
+ value_list *vals; /* looks like these may be ignored... */
+} MSIINSERTVIEW;
+
+static UINT INSERT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+
+ TRACE("%p %d %d %p\n", iv, row, col, val );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT INSERT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+ UINT n, type, val, r, row, col_count = 0;
+ MSIVIEW *sv;
+
+ TRACE("%p %p\n", iv, record );
+
+ sv = iv->sv;
+ if( !sv )
+ return ERROR_FUNCTION_FAILED;
+
+ r = sv->ops->execute( sv, 0 );
+ TRACE("tv execute returned %x\n", r);
+ if( r )
+ return r;
+
+ r = sv->ops->get_dimensions( sv, NULL, &col_count );
+ if( r )
+ goto err;
+
+ n = MSI_RecordGetFieldCount( record );
+ if( n != col_count )
+ {
+ ERR("Number of fields do not match\n");
+ goto err;
+ }
+
+ row = -1;
+ r = sv->ops->insert_row( sv, &row );
+ TRACE("insert_row returned %x\n", r);
+ if( r )
+ goto err;
+
+ for( n = 1; n <= col_count; n++ )
+ {
+ r = sv->ops->get_column_info( sv, n, NULL, &type );
+ if( r )
+ break;
+
+ if( type & MSITYPE_STRING )
+ {
+ const WCHAR *str = MSI_RecordGetString( record, n );
+ val = msi_addstringW( iv->db->strings, 0, str, -1, 1 );
+ }
+ else
+ {
+ val = MSI_RecordGetInteger( record, n );
+ val |= 0x8000;
+ }
+ r = sv->ops->set_int( sv, row, n, val );
+ if( r )
+ break;
+ }
+
+err:
+ return ERROR_SUCCESS;
+}
+
+
+static UINT INSERT_close( struct tagMSIVIEW *view )
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+ MSIVIEW *sv;
+
+ TRACE("%p\n", iv);
+
+ sv = iv->sv;
+ if( !sv )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->ops->close( sv );
+}
+
+static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+ MSIVIEW *sv;
+
+ TRACE("%p %p %p\n", iv, rows, cols );
+
+ sv = iv->sv;
+ if( !sv )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->ops->get_dimensions( sv, rows, cols );
+}
+
+static UINT INSERT_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+ MSIVIEW *sv;
+
+ TRACE("%p %d %p %p\n", iv, n, name, type );
+
+ sv = iv->sv;
+ if( !sv )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->ops->get_column_info( sv, n, name, type );
+}
+
+static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+
+ TRACE("%p %d %ld\n", iv, eModifyMode, hrec );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT INSERT_delete( struct tagMSIVIEW *view )
+{
+ MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
+ MSIVIEW *sv;
+
+ TRACE("%p\n", iv );
+
+ sv = iv->sv;
+ if( sv )
+ sv->ops->delete( sv );
+ delete_value_list( iv->vals );
+ msiobj_release( &iv->db->hdr );
+ HeapFree( GetProcessHeap(), 0, iv );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS insert_ops =
+{
+ INSERT_fetch_int,
+ NULL,
+ NULL,
+ NULL,
+ INSERT_execute,
+ INSERT_close,
+ INSERT_get_dimensions,
+ INSERT_get_column_info,
+ INSERT_modify,
+ INSERT_delete
+};
+
+UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+ string_list *columns, value_list *values, BOOL temp )
+{
+ MSIINSERTVIEW *iv = NULL;
+ UINT r;
+ MSIVIEW *tv = NULL, *sv = NULL;
+
+ TRACE("%p\n", iv );
+
+ r = TABLE_CreateView( db, table, &tv );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = SELECT_CreateView( db, &sv, tv, columns );
+ if( r != ERROR_SUCCESS )
+ {
+ if( tv )
+ tv->ops->delete( tv );
+ return r;
+ }
+
+ iv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *iv );
+ if( !iv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ iv->view.ops = &insert_ops;
+ msiobj_addref( &db->hdr );
+ iv->db = db;
+ iv->vals = values;
+ iv->bIsTemp = temp;
+ iv->sv = sv;
+ *view = (MSIVIEW*) iv;
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N msi.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ msi.c 13 Dec 2004 16:18:26 -0000 1.3.2.1
@@ -0,0 +1,1587 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002,2003,2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "wincrypt.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+#include "winver.h"
+
+#include "initguid.h"
+
+UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf);
+
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
+ * which is a problem because LPCTSTR isn't defined when compiling wine.
+ * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
+ * and make sure to only use it in W functions.
+ */
+#define LPCTSTR LPCWSTR
+
+DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000, 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+static const WCHAR szInstaller[] = {
+'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'I','n','s','t','a','l','l','e','r',0 };
+
+static const WCHAR szFeatures[] = {
+'F','e','a','t','u','r','e','s',0 };
+static const WCHAR szComponents[] = {
+'C','o','m','p','o','n','e','n','t','s',0 };
+
+/* the UI level */
+INSTALLUILEVEL gUILevel;
+HWND gUIhwnd;
+INSTALLUI_HANDLERA gUIHandler;
+DWORD gUIFilter;
+LPVOID gUIContext;
+WCHAR gszLogFile[MAX_PATH];
+
+/*
+ * .MSI file format
+ *
+ * A .msi file is a structured storage file.
+ * It should contain a number of streams.
+ */
+
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
+{
+ DWORD i,n=0;
+
+ out[n++]='{';
+ for(i=0; i<8; i++)
+ out[n++] = in[7-i];
+ out[n++]='-';
+ for(i=0; i<4; i++)
+ out[n++] = in[11-i];
+ out[n++]='-';
+ for(i=0; i<4; i++)
+ out[n++] = in[15-i];
+ out[n++]='-';
+ for(i=0; i<2; i++)
+ {
+ out[n++] = in[17+i*2];
+ out[n++] = in[16+i*2];
+ }
+ out[n++]='-';
+ for( ; i<8; i++)
+ {
+ out[n++] = in[17+i*2];
+ out[n++] = in[16+i*2];
+ }
+ out[n++]='}';
+ out[n]=0;
+ return TRUE;
+}
+
+BOOL squash_guid(LPCWSTR in, LPWSTR out)
+{
+ DWORD i,n=0;
+
+ if(in[n++] != '{')
+ return FALSE;
+ for(i=0; i<8; i++)
+ out[7-i] = in[n++];
+ if(in[n++] != '-')
+ return FALSE;
+ for(i=0; i<4; i++)
+ out[11-i] = in[n++];
+ if(in[n++] != '-')
+ return FALSE;
+ for(i=0; i<4; i++)
+ out[15-i] = in[n++];
+ if(in[n++] != '-')
+ return FALSE;
+ for(i=0; i<2; i++)
+ {
+ out[17+i*2] = in[n++];
+ out[16+i*2] = in[n++];
+ }
+ if(in[n++] != '-')
+ return FALSE;
+ for( ; i<8; i++)
+ {
+ out[17+i*2] = in[n++];
+ out[16+i*2] = in[n++];
+ }
+ out[32]=0;
+ if(in[n++] != '}')
+ return FALSE;
+ if(in[n])
+ return FALSE;
+ return TRUE;
+}
+
+/* tables for encoding and decoding base85 */
+static const unsigned char table_dec85[0x80] = {
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
+0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
+0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
+0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
+0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
+0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
+};
+
+static const char table_enc85[] =
+"!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
+"PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
+"yz{}~";
+
+/*
+ * Converts a base85 encoded guid into a GUID pointer
+ * Base85 encoded GUIDs should be 20 characters long.
+ *
+ * returns TRUE if successful, FALSE if not
+ */
+BOOL decode_base85_guid( LPCWSTR str, GUID *guid )
+{
+ DWORD i, val = 0, base = 1, *p;
+
+ p = (DWORD*) guid;
+ for( i=0; i<20; i++ )
+ {
+ if( (i%5) == 0 )
+ {
+ val = 0;
+ base = 1;
+ }
+ val += table_dec85[str[i]] * base;
+ if( str[i] >= 0x80 )
+ return FALSE;
+ if( table_dec85[str[i]] == 0xff )
+ return FALSE;
+ if( (i%5) == 4 )
+ p[i/5] = val;
+ base *= 85;
+ }
+ return TRUE;
+}
+
+/*
+ * Encodes a base85 guid given a GUID pointer
+ * Caller should provide a 21 character buffer for the encoded string.
+ *
+ * returns TRUE if successful, FALSE if not
+ */
+BOOL encode_base85_guid( GUID *guid, LPWSTR str )
+{
+ unsigned int x, *p, i;
+
+ p = (unsigned int*) guid;
+ for( i=0; i<4; i++ )
+ {
+ x = p[i];
+ *str++ = table_enc85[x%85];
+ x = x/85;
+ *str++ = table_enc85[x%85];
+ x = x/85;
+ *str++ = table_enc85[x%85];
+ x = x/85;
+ *str++ = table_enc85[x%85];
+ x = x/85;
+ *str++ = table_enc85[x%85];
+ }
+ *str = 0;
+
+ return TRUE;
+}
+
+
+VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
+{
+ MSIDATABASE *db = (MSIDATABASE *) arg;
+
+ free_cached_tables( db );
+ IStorage_Release( db->storage );
+}
+
+UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
+{
+ IStorage *stg = NULL;
+ HRESULT r;
+ MSIDATABASE *db = NULL;
+ UINT ret = ERROR_FUNCTION_FAILED;
+ LPWSTR szMode;
+ STATSTG stat;
+
+ TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
+
+ if( !pdb )
+ return ERROR_INVALID_PARAMETER;
+
+ szMode = (LPWSTR) szPersist;
+ if( HIWORD( szPersist ) )
+ {
+ /* UINT len = lstrlenW( szPerist ) + 1; */
+ FIXME("don't support persist files yet\b");
+ return ERROR_INVALID_PARAMETER;
+ /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
+ }
+ else if( szPersist == MSIDBOPEN_READONLY )
+ {
+ r = StgOpenStorage( szDBPath, NULL,
+ STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
+ }
+ else if( szPersist == MSIDBOPEN_CREATE )
+ {
+ r = StgCreateDocfile( szDBPath,
+ STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
+ if( r == ERROR_SUCCESS )
+ {
+ IStorage_SetClass( stg, &CLSID_MsiDatabase );
+ r = init_string_table( stg );
+ }
+ }
+ else if( szPersist == MSIDBOPEN_TRANSACT )
+ {
+ r = StgOpenStorage( szDBPath, NULL,
+ STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
+ }
+ else
+ {
+ ERR("unknown flag %p\n",szPersist);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if( FAILED( r ) )
+ {
+ FIXME("open failed r = %08lx!\n",r);
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
+ if( FAILED( r ) )
+ {
+ FIXME("Failed to stat storage\n");
+ goto end;
+ }
+
+ if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
+ {
+ ERR("storage GUID is not a MSI database GUID %s\n",
+ debugstr_guid(&stat.clsid) );
+ goto end;
+ }
+
+
+ db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
+ MSI_CloseDatabase );
+ if( !db )
+ {
+ FIXME("Failed to allocate a handle\n");
+ goto end;
+ }
+
+ if( TRACE_ON( msi ) )
+ enum_stream_names( stg );
+
+ db->storage = stg;
+ db->mode = szMode;
+
+ ret = load_string_table( db );
+ if( ret != ERROR_SUCCESS )
+ goto end;
+
+ msiobj_addref( &db->hdr );
+ IStorage_AddRef( stg );
+ *pdb = db;
+
+end:
+ if( db )
+ msiobj_release( &db->hdr );
+ if( stg )
+ IStorage_Release( stg );
+
+ return ret;
+}
+
+UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
+{
+ MSIDATABASE *db;
+ UINT ret;
+
+ TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
+
+ ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
+ if( ret == ERROR_SUCCESS )
+ {
+ *phDB = alloc_msihandle( &db->hdr );
+ msiobj_release( &db->hdr );
+ }
+
+ return ret;
+}
+
+UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
+{
+ HRESULT r = ERROR_FUNCTION_FAILED;
+ LPWSTR szwDBPath = NULL, szwPersist = NULL;
+ UINT len;
+
+ TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
+
+ if( szDBPath )
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
+ szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwDBPath )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
+ }
+
+ if( HIWORD(szPersist) )
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
+ szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwPersist )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
+ }
+ else
+ szwPersist = (LPWSTR) szPersist;
+
+ r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
+
+end:
+ if( szwPersist )
+ HeapFree( GetProcessHeap(), 0, szwPersist );
+ if( szwDBPath )
+ HeapFree( GetProcessHeap(), 0, szwDBPath );
+
+ return r;
+}
+
+UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
+{
+ UINT len, ret;
+ LPWSTR szwProd = NULL;
+
+ TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
+
+ if( szProduct )
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+ szwProd = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ if( szwProd )
+ MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProd, len );
+ }
+
+ ret = MsiOpenProductW( szwProd, phProduct );
+
+ if( szwProd )
+ HeapFree( GetProcessHeap(), 0, szwProd );
+
+ return ret;
+}
+
+UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
+{
+ static const WCHAR szKey[] = {
+ 'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+ 'U','n','i','n','s','t','a','l','l',0 };
+ static const WCHAR szLocalPackage[] = {
+ 'L','o','c','a','l','P','a','c','k','a','g','e', 0
+ };
+ LPWSTR path = NULL;
+ UINT r;
+ HKEY hKeyProduct = NULL, hKeyUninstall = NULL;
+ DWORD count, type;
+
+ TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
+
+ r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
+ if( r != ERROR_SUCCESS )
+ return ERROR_UNKNOWN_PRODUCT;
+
+ r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
+ if( r != ERROR_SUCCESS )
+ {
+ r = ERROR_UNKNOWN_PRODUCT;
+ goto end;
+ }
+
+ /* find the size of the path */
+ type = count = 0;
+ r = RegQueryValueExW( hKeyProduct, szLocalPackage,
+ NULL, &type, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ {
+ r = ERROR_UNKNOWN_PRODUCT;
+ goto end;
+ }
+
+ /* now alloc and fetch the path of the database to open */
+ path = HeapAlloc( GetProcessHeap(), 0, count );
+ if( !path )
+ goto end;
+
+ r = RegQueryValueExW( hKeyProduct, szLocalPackage,
+ NULL, &type, (LPBYTE) path, &count );
+ if( r != ERROR_SUCCESS )
+ {
+ r = ERROR_UNKNOWN_PRODUCT;
+ goto end;
+ }
+
+ r = MsiOpenPackageW( path, phProduct );
+
+end:
+ if( path )
+ HeapFree( GetProcessHeap(), 0, path );
+ if( hKeyProduct )
+ RegCloseKey( hKeyProduct );
+ RegCloseKey( hKeyUninstall );
+
+ return r;
+}
+
+UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage)
+{
+ FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage)
+{
+ FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
+{
+ FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
+ debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage, dwPlatform, dwOptions);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
+{
+ FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
+ debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage, dwPlatform, dwOptions);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
+{
+ LPWSTR szwPath = NULL, szwCommand = NULL;
+ UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */
+
+ TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
+
+ if( szPackagePath )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, NULL, 0 );
+ szwPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwPath )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, szwPath, len );
+ }
+
+ if( szCommandLine )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
+ szwCommand = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwCommand )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommand, len );
+ }
+
+ r = MsiInstallProductW( szwPath, szwCommand );
+
+end:
+ if( szwPath )
+ HeapFree( GetProcessHeap(), 0, szwPath );
+
+ if( szwCommand )
+ HeapFree( GetProcessHeap(), 0, szwCommand );
+
+ return r;
+}
+
+UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
+{
+ MSIPACKAGE *package = NULL;
+ UINT rc = ERROR_SUCCESS;
+ MSIHANDLE handle;
+
+ FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
+
+ rc = MsiVerifyPackageW(szPackagePath);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
+ rc = MSI_OpenPackageW(szPackagePath,&package);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
+ handle = alloc_msihandle( &package->hdr );
+
+ rc = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
+
+ MsiCloseHandle(handle);
+ msiobj_release( &package->hdr );
+ return rc;
+}
+
+UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
+{
+ FIXME("%s 0x%08lx\n", debugstr_a(szProduct), dwReinstallMode);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
+{
+ FIXME("%s 0x%08lx\n", debugstr_w(szProduct), dwReinstallMode);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage, INSTALLTYPE eInstallType, LPCSTR szCommandLine)
+{
+ FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage), eInstallType, debugstr_a(szCommandLine));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage, INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
+{
+ FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage), eInstallType, debugstr_w(szCommandLine));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
+{
+ LPWSTR szwProduct = NULL;
+ UINT hr = ERROR_SUCCESS;
+
+ FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
+
+ if( szProduct )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+ szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwProduct )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+ }
+
+ hr = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
+
+end:
+ if( szwProduct )
+ HeapFree( GetProcessHeap(), 0, szwProduct );
+
+ return hr;
+}
+
+UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
+{
+ FIXME("%s %d %d\n",debugstr_w(szProduct), iInstallLevel, eInstallState);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
+{
+ LPWSTR szwComponent = NULL, szwBuffer = NULL;
+ UINT hr = ERROR_INSTALL_FAILURE;
+
+ FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
+
+ if( szComponent )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
+ szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwComponent )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
+ } else {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ {
+ szwBuffer = HeapAlloc( GetProcessHeap(), 0, GUID_SIZE * sizeof(WCHAR) );
+ if( !szwBuffer )
+ goto end;
+ }
+
+ hr = MsiGetProductCodeW( szwComponent, szwBuffer );
+
+ if( ERROR_SUCCESS == hr )
+ {
+ WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
+ }
+
+end:
+ if( szwComponent )
+ HeapFree( GetProcessHeap(), 0, szwComponent );
+ if( szwBuffer )
+ HeapFree( GetProcessHeap(), 0, szwBuffer );
+
+ return hr;
+}
+
+UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
+{
+ FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
+ if (NULL == szComponent) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+
+
+UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, DWORD *pcchValueBuf)
+{
+ LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
+ UINT hr = ERROR_INSTALL_FAILURE;
+
+ FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute), szBuffer, pcchValueBuf);
+
+ if (NULL != szBuffer && NULL == pcchValueBuf) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ if( szProduct )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+ szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwProduct )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+ } else {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if( szAttribute )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, NULL, 0 );
+ szwAttribute = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwAttribute )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szAttribute, -1, szwAttribute, len );
+ } else {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if( szBuffer )
+ {
+ szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
+ if( !szwBuffer )
+ goto end;
+ }
+
+ hr = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
+
+ if( ERROR_SUCCESS == hr )
+ {
+ WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
+ }
+
+end:
+ if( szwProduct )
+ HeapFree( GetProcessHeap(), 0, szwProduct );
+ if( szwAttribute )
+ HeapFree( GetProcessHeap(), 0, szwAttribute );
+ if( szwBuffer )
+ HeapFree( GetProcessHeap(), 0, szwBuffer );
+
+ return hr;
+}
+
+UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szBuffer, DWORD *pcchValueBuf)
+{
+ MSIHANDLE hProduct;
+ UINT hr;
+
+ FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute), szBuffer, pcchValueBuf);
+
+ if (NULL != szBuffer && NULL == pcchValueBuf) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ if (NULL == szProduct || NULL == szAttribute) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ hr = MsiOpenProductW(szProduct, &hProduct);
+ if (ERROR_SUCCESS != hr) return hr;
+
+ hr = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
+ MsiCloseHandle(hProduct);
+ return hr;
+}
+
+UINT WINAPI MsiDatabaseImportA(LPCSTR szFolderPath, LPCSTR szFilename)
+{
+ FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseImportW(LPCWSTR szFolderPath, LPCWSTR szFilename)
+{
+ FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
+{
+ LPWSTR szwLogFile = NULL;
+ UINT hr = ERROR_INSTALL_FAILURE;
+
+ FIXME("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
+
+ if( szLogFile )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, NULL, 0 );
+ szwLogFile = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwLogFile )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szLogFile, -1, szwLogFile, len );
+ } else {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ hr = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
+
+end:
+ if( szwLogFile )
+ HeapFree( GetProcessHeap(), 0, szwLogFile );
+
+ return hr;
+}
+
+UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
+{
+ HANDLE the_file = INVALID_HANDLE_VALUE;
+ TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
+ strcpyW(gszLogFile,szLogFile);
+ if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
+ DeleteFileW(szLogFile);
+ the_file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (the_file != INVALID_HANDLE_VALUE)
+ CloseHandle(the_file);
+ else
+ ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
+
+ return ERROR_SUCCESS;
+}
+
+INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
+{
+ FIXME("%s\n", debugstr_a(szProduct));
+ return INSTALLSTATE_UNKNOWN;
+}
+
+INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
+{
+ FIXME("%s\n", debugstr_w(szProduct));
+ return INSTALLSTATE_UNKNOWN;
+}
+
+INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
+{
+ INSTALLUILEVEL old = gUILevel;
+ HWND oldwnd = gUIhwnd;
+ TRACE("%08x %p\n", dwUILevel, phWnd);
+
+ gUILevel = dwUILevel;
+ if (phWnd)
+ {
+ gUIhwnd = *phWnd;
+ *phWnd = oldwnd;
+ }
+ return old;
+}
+
+INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
+ DWORD dwMessageFilter, LPVOID pvContext)
+{
+ INSTALLUI_HANDLERA prev = gUIHandler;
+
+ TRACE("(%p %lx %p)\n",puiHandler,dwMessageFilter,pvContext);
+ gUIHandler = puiHandler;
+ gUIFilter = dwMessageFilter;
+ gUIContext = pvContext;
+
+ return prev;
+}
+
+UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, int nBufferMax, DWORD e)
+{
+ /*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
+ FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiLoadStringW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax, DWORD e)
+{
+ FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e);
+ /*
+ int ret = LoadStringW(hInstance,uID,lpBuffer,nBufferMax);
+ FIXME("%s\n",debugstr_w(lpBuffer));
+ return ret;
+ */
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf, DWORD *pcchBuf)
+{
+ FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
+ return INSTALLSTATE_UNKNOWN;
+}
+
+INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf, DWORD *pcchBuf)
+{
+ FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
+ return INSTALLSTATE_UNKNOWN;
+}
+
+#include "winuser.h"
+
+UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType, WORD wLanguageId, DWORD f)
+{
+ FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),uType,wLanguageId,f);
+ /*
+ MessageBoxExA(hWnd,lpText,lpCaption,uType|MB_OK,wLanguageId);
+ */
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType, WORD wLanguageId, DWORD f)
+{
+ /*FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);*/
+ FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),uType,wLanguageId,f);
+ /*
+ MessageBoxExW(hWnd,lpText,lpCaption,uType|MB_OK,wLanguageId);
+ */
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
+{
+ DWORD r;
+ WCHAR szwGuid[GUID_SIZE];
+
+ TRACE("%ld %p\n",index,lpguid);
+
+ if (NULL == lpguid) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ r = MsiEnumProductsW(index, szwGuid);
+ if( r == ERROR_SUCCESS )
+ WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
+
+ return r;
+}
+
+UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
+{
+ HKEY hkey = 0, hkeyFeatures = 0;
+ DWORD r;
+ WCHAR szKeyName[33];
+
+ TRACE("%ld %p\n",index,lpguid);
+
+ if (NULL == lpguid) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
+ if( r != ERROR_SUCCESS )
+ goto end;
+
+ r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
+ if( r != ERROR_SUCCESS )
+ goto end;
+
+ r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);
+
+ unsquash_guid(szKeyName, lpguid);
+
+end:
+
+ if( hkeyFeatures )
+ RegCloseKey(hkeyFeatures);
+ if( hkey )
+ RegCloseKey(hkey);
+
+ return r;
+}
+
+UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index,
+ LPSTR szFeature, LPSTR szParent)
+{
+ DWORD r;
+ WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];
+ LPWSTR szwProduct = NULL;
+
+ TRACE("%s %ld %p %p\n",debugstr_a(szProduct),index,szFeature,szParent);
+
+ if( szProduct )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
+ szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ if( szwProduct )
+ MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
+ else
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);
+ if( r == ERROR_SUCCESS )
+ {
+ WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,
+ szFeature, GUID_SIZE, NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, szwParent, -1,
+ szParent, GUID_SIZE, NULL, NULL);
+ }
+
+ if( szwProduct )
+ HeapFree( GetProcessHeap(), 0, szwProduct);
+
+ return r;
+}
+
+UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
+ LPWSTR szFeature, LPWSTR szParent)
+{
+ HKEY hkey = 0, hkeyFeatures = 0, hkeyProduct = 0;
+ DWORD r, sz;
+ WCHAR szRegName[GUID_SIZE];
+
+ TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
+
+ if( !squash_guid(szProduct, szRegName) )
+ return ERROR_INVALID_PARAMETER;
[truncated at 1000 lines; 591 more skipped]
reactos/lib/msi
diff -N msi.spec
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ msi.spec 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,236 @@
+1 stdcall -private DllCanUnloadNow() MSI_DllCanUnloadNow
+2 stdcall -private DllGetClassObject(ptr ptr ptr) MSI_DllGetClassObject
+3 stdcall -private DllRegisterServer() MSI_DllRegisterServer
+4 stdcall -private DllUnregisterServer() MSI_DllUnregisterServer
+5 stdcall MsiAdvertiseProductA(str str str long)
+6 stdcall MsiAdvertiseProductW(wstr wstr wstr long)
+7 stdcall MsiCloseAllHandles()
+8 stdcall MsiCloseHandle(long)
+9 stub MsiCollectUserInfoA
+10 stub MsiCollectUserInfoW
+11 stub MsiConfigureFeatureA
+12 stub MsiConfigureFeatureFromDescriptorA
+13 stub MsiConfigureFeatureFromDescriptorW
+14 stub MsiConfigureFeatureW
+15 stdcall MsiConfigureProductA(str long long)
+16 stdcall MsiConfigureProductW(wstr long long)
+17 stdcall MsiCreateRecord(long)
+18 stdcall MsiDatabaseApplyTransformA(long str long)
+19 stdcall MsiDatabaseApplyTransformW(long wstr long)
+20 stdcall MsiDatabaseCommit(long)
+21 stub MsiDatabaseExportA
+22 stub MsiDatabaseExportW
+23 stdcall MsiDatabaseGenerateTransformA(long long str long long)
+24 stdcall MsiDatabaseGenerateTransformW(long long wstr long long)
+25 stdcall MsiDatabaseGetPrimaryKeysA(long str ptr)
+26 stdcall MsiDatabaseGetPrimaryKeysW(long wstr ptr)
+27 stdcall MsiDatabaseImportA(str str)
+28 stdcall MsiDatabaseImportW(wstr wstr)
+29 stub MsiDatabaseMergeA
+30 stub MsiDatabaseMergeW
+31 stdcall MsiDatabaseOpenViewA(long str ptr)
+32 stdcall MsiDatabaseOpenViewW(long wstr ptr)
+33 stdcall MsiDoActionA(long str)
+34 stdcall MsiDoActionW(long wstr)
+35 stub MsiEnableUIPreview
+36 stdcall MsiEnumClientsA(str long ptr)
+37 stdcall MsiEnumClientsW(wstr long ptr)
+38 stdcall MsiEnumComponentQualifiersA(str long str ptr str ptr)
+39 stdcall MsiEnumComponentQualifiersW(wstr long wstr ptr wstr ptr)
+40 stdcall MsiEnumComponentsA(long ptr)
+41 stdcall MsiEnumComponentsW(long ptr)
+42 stdcall MsiEnumFeaturesA(str long ptr ptr)
+43 stdcall MsiEnumFeaturesW(wstr long ptr ptr)
+44 stdcall MsiEnumProductsA(long ptr)
+45 stdcall MsiEnumProductsW(long ptr)
+46 stdcall MsiEvaluateConditionA(long str)
+47 stdcall MsiEvaluateConditionW(long wstr)
+48 stub MsiGetLastErrorRecord
+49 stdcall MsiGetActiveDatabase(long)
+50 stdcall MsiGetComponentStateA(long str ptr ptr)
+51 stdcall MsiGetComponentStateW(long wstr ptr ptr)
+52 stub MsiGetDatabaseState
+53 stub MsiGetFeatureCostA
+54 stub MsiGetFeatureCostW
+55 stub MsiGetFeatureInfoA
+56 stub MsiGetFeatureInfoW
+57 stdcall MsiGetFeatureStateA(long str ptr ptr)
+58 stdcall MsiGetFeatureStateW(long wstr ptr ptr)
+59 stub MsiGetFeatureUsageA
+60 stub MsiGetFeatureUsageW
+61 stub MsiGetFeatureValidStatesA
+62 stub MsiGetFeatureValidStatesW
+63 stub MsiGetLanguage
+64 stdcall MsiGetMode(long long)
+65 stdcall MsiGetProductCodeA(str str)
+66 stdcall MsiGetProductCodeW(wstr wstr)
+67 stdcall MsiGetProductInfoA(str str str long)
+68 stub MsiGetProductInfoFromScriptA
+69 stub MsiGetProductInfoFromScriptW
+70 stdcall MsiGetProductInfoW(wstr wstr wstr long)
+71 stdcall MsiGetProductPropertyA(long str ptr ptr)
+72 stdcall MsiGetProductPropertyW(long wstr ptr ptr)
+73 stdcall MsiGetPropertyA(ptr str str ptr)
+74 stdcall MsiGetPropertyW(ptr wstr wstr ptr)
+75 stdcall MsiGetSourcePathA(long str ptr ptr)
+76 stdcall MsiGetSourcePathW(long wstr ptr ptr)
+77 stdcall MsiGetSummaryInformationA(long str long ptr)
+78 stdcall MsiGetSummaryInformationW(long wstr long ptr)
+79 stdcall MsiGetTargetPathA(long str ptr ptr)
+80 stdcall MsiGetTargetPathW(long wstr ptr ptr)
+81 stub MsiGetUserInfoA
+82 stub MsiGetUserInfoW
+83 stub MsiInstallMissingComponentA
+84 stub MsiInstallMissingComponentW
+85 stub MsiInstallMissingFileA
+86 stub MsiInstallMissingFileW
+87 stdcall MsiInstallProductA(str str)
+88 stdcall MsiInstallProductW(wstr wstr)
+89 stdcall MsiLocateComponentA(str ptr long)
+90 stdcall MsiLocateComponentW(wstr ptr long)
+91 stdcall MsiOpenDatabaseA(str str ptr)
+92 stdcall MsiOpenDatabaseW(wstr wstr ptr)
+93 stdcall MsiOpenPackageA(str ptr)
+94 stdcall MsiOpenPackageW(wstr ptr)
+95 stdcall MsiOpenProductA(str ptr)
+96 stdcall MsiOpenProductW(wstr ptr)
+97 stub MsiPreviewBillboardA
+98 stub MsiPreviewBillboardW
+99 stub MsiPreviewDialogA
+100 stub MsiPreviewDialogW
+101 stub MsiProcessAdvertiseScriptA
+102 stub MsiProcessAdvertiseScriptW
+103 stdcall MsiProcessMessage(long long long)
+104 stub MsiProvideComponentA
+105 stdcall MsiProvideComponentFromDescriptorA(str ptr ptr ptr)
+106 stdcall MsiProvideComponentFromDescriptorW(wstr ptr ptr ptr)
+107 stub MsiProvideComponentW
+108 stub MsiProvideQualifiedComponentA
+109 stub MsiProvideQualifiedComponentW
+110 stdcall MsiQueryFeatureStateA(str str)
+111 stdcall MsiQueryFeatureStateW(wstr wstr)
+112 stdcall MsiQueryProductStateA(str)
+113 stdcall MsiQueryProductStateW(wstr)
+114 stdcall MsiRecordDataSize(long long)
+115 stdcall MsiRecordGetFieldCount(long)
+116 stdcall MsiRecordGetInteger(long long)
+117 stdcall MsiRecordGetStringA(long long ptr ptr)
+118 stdcall MsiRecordGetStringW(long long ptr ptr)
+119 stdcall MsiRecordIsNull(long long)
+120 stdcall MsiRecordReadStream(long long ptr ptr)
+121 stdcall MsiRecordSetInteger(long long long)
+122 stdcall MsiRecordSetStreamA(long long str)
+123 stdcall MsiRecordSetStreamW(long long wstr)
+124 stdcall MsiRecordSetStringA(long long str)
+125 stdcall MsiRecordSetStringW(long long wstr)
+126 stub MsiReinstallFeatureA
+127 stub MsiReinstallFeatureFromDescriptorA
+128 stub MsiReinstallFeatureFromDescriptorW
+129 stub MsiReinstallFeatureW
+130 stdcall MsiReinstallProductA(str long)
+131 stdcall MsiReinstallProductW(wstr long)
+132 stub MsiSequenceA
+133 stub MsiSequenceW
+134 stub MsiSetComponentStateA
+135 stub MsiSetComponentStateW
+136 stdcall MsiSetExternalUIA(ptr long ptr)
+137 stub MsiSetExternalUIW
+138 stdcall MsiSetFeatureStateA(long str long)
+139 stdcall MsiSetFeatureStateW(long wstr long)
+140 stub MsiSetInstallLevel
+141 stdcall MsiSetInternalUI(long ptr)
+142 stub MsiVerifyDiskSpace
+143 stub MsiSetMode
+144 stdcall MsiSetPropertyA(long str str)
+145 stdcall MsiSetPropertyW(long wstr wstr)
+146 stdcall MsiSetTargetPathA(long str str)
+147 stdcall MsiSetTargetPathW(long wstr wstr)
+148 stdcall MsiSummaryInfoGetPropertyA(long long ptr ptr ptr ptr ptr)
+149 stdcall MsiSummaryInfoGetPropertyCount(long ptr)
+150 stdcall MsiSummaryInfoGetPropertyW(long long ptr ptr ptr ptr ptr)
+151 stub MsiSummaryInfoPersist
+152 stub MsiSummaryInfoSetPropertyA
+153 stub MsiSummaryInfoSetPropertyW
+154 stub MsiUseFeatureA
+155 stub MsiUseFeatureW
+156 stdcall MsiVerifyPackageA(str)
+157 stdcall MsiVerifyPackageW(wstr)
+158 stdcall MsiViewClose(long)
+159 stdcall MsiViewExecute(long long)
+160 stdcall MsiViewFetch(long ptr)
+161 stub MsiViewGetErrorA
+162 stub MsiViewGetErrorW
+163 stdcall MsiViewModify(long long long)
+164 stdcall MsiDatabaseIsTablePersistentA(long str)
+165 stdcall MsiDatabaseIsTablePersistentW(long wstr)
+166 stdcall MsiViewGetColumnInfo(long long ptr)
+167 stdcall MsiRecordClearData(long)
+168 stdcall MsiEnableLogA(long str long)
+169 stdcall MsiEnableLogW(long wstr long)
+170 stdcall MsiFormatRecordA(long long ptr ptr)
+171 stdcall MsiFormatRecordW(long long ptr ptr)
+172 stdcall MsiGetComponentPathA(str str ptr ptr)
+173 stdcall MsiGetComponentPathW(wstr wstr ptr ptr)
+174 stdcall MsiApplyPatchA(str str long str)
+175 stdcall MsiApplyPatchW(wstr wstr long wstr)
+176 stub MsiAdvertiseScriptA
+177 stub MsiAdvertiseScriptW
+178 stub MsiGetPatchInfoA
+179 stub MsiGetPatchInfoW
+180 stub MsiEnumPatchesA
+181 stub MsiEnumPatchesW
+182 stdcall DllGetVersion(ptr) MSI_DllGetVersion
+183 stub MsiGetProductCodeFromPackageCodeA
+184 stub MsiGetProductCodeFromPackageCodeW
+185 stub MsiCreateTransformSummaryInfoA
+186 stub MsiCreateTransformSummaryInfoW
+187 stub MsiQueryFeatureStateFromDescriptorA
+188 stub MsiQueryFeatureStateFromDescriptorW
+189 stub MsiConfigureProductExA
+190 stub MsiConfigureProductExW
+191 stub MsiInvalidateFeatureCache
+192 stub MsiUseFeatureExA
+193 stub MsiUseFeatureExW
+194 stdcall MsiGetFileVersionA(str str ptr str ptr)
+195 stdcall MsiGetFileVersionW(wstr wstr ptr wstr ptr)
+196 stdcall MsiLoadStringA(long long long long long)
+197 stdcall MsiLoadStringW(long long long long long)
+198 stdcall MsiMessageBoxA(long long long long long long)
+199 stdcall MsiMessageBoxW(long long long long long long)
+200 stub MsiDecomposeDescriptorA
+201 stub MsiDecomposeDescriptorW
+202 stub MsiProvideQualifiedComponentExA
+203 stub MsiProvideQualifiedComponentExW
+204 stdcall MsiEnumRelatedProductsA(str long long str)
+205 stub MsiEnumRelatedProductsW
+206 stub MsiSetFeatureAttributesA
+207 stub MsiSetFeatureAttributesW
+208 stub MsiSourceListClearAllA
+209 stub MsiSourceListClearAllW
+210 stub MsiSourceListAddSourceA
+211 stub MsiSourceListAddSourceW
+212 stub MsiSourceListForceResolutionA
+213 stub MsiSourceListForceResolutionW
+214 stub MsiIsProductElevatedA
+215 stub MsiIsProductElevatedW
+216 stub MsiGetShortcutTargetA
+217 stub MsiGetShortcutTargetW
+218 stub MsiGetFileHashA
+219 stub MsiGetFileHashW
+220 stub MsiEnumComponentCostsA
+221 stub MsiEnumComponentCostsW
+222 stub MsiCreateAndVerifyInstallerDirectory
+223 stdcall MsiGetFileSignatureInformationA(str long ptr ptr ptr)
+224 stdcall MsiGetFileSignatureInformationW(wstr long ptr ptr ptr)
+225 stdcall MsiProvideAssemblyA(str str long long str ptr)
+226 stdcall MsiProvideAssemblyW(wstr wstr long long wstr ptr)
+227 stdcall MsiAdvertiseProductExA(str str str long long long)
+228 stdcall MsiAdvertiseProductExW(wstr wstr wstr long long long)
+229 stub MsiNotifySidChangeA
+230 stub MsiNotifySidChangeW
+231 stdcall MsiOpenPackageExA(str long ptr)
+232 stdcall MsiOpenPackageExW(wstr long ptr)
+233 stub MsiDeleteUserDataA
+234 stub MsiDeleteUserDataW
+235 stub Migrate10CachedPackagesA
+236 stub Migrate10CachedPackagesW
reactos/lib/msi
diff -N msipriv.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ msipriv.h 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,325 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_MSI_PRIVATE__
+#define __WINE_MSI_PRIVATE__
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+
+#define MSI_DATASIZEMASK 0x00ff
+#define MSITYPE_VALID 0x0100
+#define MSITYPE_STRING 0x0800
+#define MSITYPE_NULLABLE 0x1000
+#define MSITYPE_KEY 0x2000
+
+#define MSITYPE_BINARY 0x8900
+
+struct tagMSITABLE;
+typedef struct tagMSITABLE MSITABLE;
+
+struct string_table;
+typedef struct string_table string_table;
+
+struct tagMSIOBJECTHDR;
+typedef struct tagMSIOBJECTHDR MSIOBJECTHDR;
+
+typedef VOID (*msihandledestructor)( MSIOBJECTHDR * );
+
+struct tagMSIOBJECTHDR
+{
+ UINT magic;
+ UINT type;
+ UINT refcount;
+ msihandledestructor destructor;
+ struct tagMSIOBJECTHDR *next;
+ struct tagMSIOBJECTHDR *prev;
+};
+
+typedef struct tagMSIDATABASE
+{
+ MSIOBJECTHDR hdr;
+ IStorage *storage;
+ string_table *strings;
+ LPWSTR mode;
+ MSITABLE *first_table, *last_table;
+} MSIDATABASE;
+
+typedef struct tagMSIVIEW MSIVIEW;
+
+typedef struct tagMSIQUERY
+{
+ MSIOBJECTHDR hdr;
+ MSIVIEW *view;
+ UINT row;
+ MSIDATABASE *db;
+} MSIQUERY;
+
+/* maybe we can use a Variant instead of doing it ourselves? */
+typedef struct tagMSIFIELD
+{
+ UINT type;
+ union
+ {
+ INT iVal;
+ LPWSTR szwVal;
+ IStream *stream;
+ } u;
+} MSIFIELD;
+
+typedef struct tagMSIRECORD
+{
+ MSIOBJECTHDR hdr;
+ UINT count; /* as passed to MsiCreateRecord */
+ MSIFIELD fields[1]; /* nb. array size is count+1 */
+} MSIRECORD;
+
+typedef struct tagMSIVIEWOPS
+{
+ /*
+ * fetch_int - reads one integer from {row,col} in the table
+ *
+ * This function should be called after the execute method.
+ * Data returned by the function should not change until
+ * close or delete is called.
+ * To get a string value, query the database's string table with
+ * the integer value returned from this function.
+ */
+ UINT (*fetch_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT *val );
+
+ /*
+ * fetch_int - reads one integer from {row,col} in the table
+ *
+ * This function is similar to fetch_int, except fetches a
+ * stream instead of an integer.
+ */
+ UINT (*fetch_stream)( struct tagMSIVIEW *, UINT row, UINT col, IStream **stm );
+
+ /*
+ * get_int - sets one integer at {row,col} in the table
+ *
+ * Similar semantics to fetch_int
+ */
+ UINT (*set_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT val );
+
+ /*
+ * Inserts a new, blank row into the database
+ * *row receives the number of the new row
+ */
+ UINT (*insert_row)( struct tagMSIVIEW *, UINT *row );
+
+ /*
+ * execute - loads the underlying data into memory so it can be read
+ */
+ UINT (*execute)( struct tagMSIVIEW *, MSIRECORD * );
+
+ /*
+ * close - clears the data read by execute from memory
+ */
+ UINT (*close)( struct tagMSIVIEW * );
+
+ /*
+ * get_dimensions - returns the number of rows or columns in a table.
+ *
+ * The number of rows can only be queried after the execute method
+ * is called. The number of columns can be queried at any time.
+ */
+ UINT (*get_dimensions)( struct tagMSIVIEW *, UINT *rows, UINT *cols );
+
+ /*
+ * get_column_info - returns the name and type of a specific column
+ *
+ * The name is HeapAlloc'ed by this function and should be freed by
+ * the caller.
+ * The column information can be queried at any time.
+ */
+ UINT (*get_column_info)( struct tagMSIVIEW *, UINT n, LPWSTR *name, UINT *type );
+
+ /*
+ * modify - not yet implemented properly
+ */
+ UINT (*modify)( struct tagMSIVIEW *, MSIMODIFY, MSIHANDLE );
+
+ /*
+ * delete - destroys the structure completely
+ */
+ UINT (*delete)( struct tagMSIVIEW * );
+
+} MSIVIEWOPS;
+
+typedef struct tagMSISUMMARYINFO
+{
+ MSIOBJECTHDR hdr;
+ IPropertyStorage *propstg;
+} MSISUMMARYINFO;
+
+struct tagMSIVIEW
+{
+ MSIOBJECTHDR hdr;
+ MSIVIEWOPS *ops;
+};
+
+typedef struct tagMSIPACKAGE
+{
+ MSIOBJECTHDR hdr;
+ MSIDATABASE *db;
+ struct tagMSIFEATURE *features;
+ UINT loaded_features;
+ struct tagMSIFOLDER *folders;
+ UINT loaded_folders;
+ struct tagMSICOMPONENT *components;
+ UINT loaded_components;
+ struct tagMSIFILE *files;
+ UINT loaded_files;
+} MSIPACKAGE;
+
+#define MSIHANDLETYPE_ANY 0
+#define MSIHANDLETYPE_DATABASE 1
+#define MSIHANDLETYPE_SUMMARYINFO 2
+#define MSIHANDLETYPE_VIEW 3
+#define MSIHANDLETYPE_RECORD 4
+#define MSIHANDLETYPE_PACKAGE 5
+
+#define MSI_MAJORVERSION 2
+#define MSI_MINORVERSION 0
+#define MSI_BUILDNUMBER 2600
+
+#define GUID_SIZE 39
+
+#define MSIHANDLE_MAGIC 0x4d434923
+#define MSIMAXHANDLES 0x80
+
+#define MSISUMINFO_OFFSET 0x30LL
+
+DEFINE_GUID(CLSID_IMsiServer, 0x000C101C,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_IMsiServerX1, 0x000C103E,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_IMsiServerX2, 0x000C1090,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+DEFINE_GUID(CLSID_IMsiServerX3, 0x000C1094,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+DEFINE_GUID(CLSID_IMsiServerMessage, 0x000C101D,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
+
+
+/* handle functions */
+extern void *msihandle2msiinfo(MSIHANDLE handle, UINT type);
+extern MSIHANDLE alloc_msihandle( MSIOBJECTHDR * );
+extern void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy );
+extern void msiobj_addref(MSIOBJECTHDR *);
+extern int msiobj_release(MSIOBJECTHDR *);
+extern MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr );
+
+/* add this table to the list of cached tables in the database */
+extern void add_table(MSIDATABASE *db, MSITABLE *table);
+extern void remove_table( MSIDATABASE *db, MSITABLE *table );
+extern void free_table( MSIDATABASE *db, MSITABLE *table );
+extern void free_cached_tables( MSIDATABASE *db );
+extern UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **table);
+extern UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **table);
+extern UINT load_string_table( MSIDATABASE *db );
+extern UINT MSI_CommitTables( MSIDATABASE *db );
+extern HRESULT init_string_table( IStorage *stg );
+
+
+/* string table functions */
+extern BOOL msi_addstring( string_table *st, int string_no, const CHAR *data, int len, UINT refcount );
+extern BOOL msi_addstringW( string_table *st, int string_no, const WCHAR *data, int len, UINT refcount );
+extern UINT msi_id2stringW( string_table *st, UINT string_no, LPWSTR buffer, UINT *sz );
+extern UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz );
+
+extern LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid);
+extern UINT msi_string2idW( string_table *st, LPCWSTR buffer, UINT *id );
+extern UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id );
+extern string_table *msi_init_stringtable( int entries, UINT codepage );
+extern VOID msi_destroy_stringtable( string_table *st );
+extern UINT msi_string_count( string_table *st );
+extern UINT msi_id_refcount( string_table *st, UINT i );
+extern UINT msi_string_totalsize( string_table *st, UINT *last );
+extern UINT msi_strcmp( string_table *st, UINT lval, UINT rval, UINT *res );
+extern const WCHAR *msi_string_lookup_id( string_table *st, UINT id );
+extern UINT msi_string_get_codepage( string_table *st );
+
+
+extern UINT VIEW_find_column( MSIVIEW *view, LPWSTR name, UINT *n );
+
+extern BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name );
+
+extern UINT read_raw_stream_data( MSIDATABASE*, LPCWSTR stname,
+ USHORT **pdata, UINT *psz );
+extern UINT ACTION_DoTopLevelINSTALL( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern void ACTION_remove_tracked_tempfiles( MSIPACKAGE* );
+
+/* record internals */
+extern UINT MSI_RecordSetIStream( MSIRECORD *, unsigned int, IStream *);
+extern const WCHAR *MSI_RecordGetString( MSIRECORD *, unsigned int );
+extern MSIRECORD *MSI_CreateRecord( unsigned int );
+extern UINT MSI_RecordSetInteger( MSIRECORD *, unsigned int, int );
+extern UINT MSI_RecordSetStringW( MSIRECORD *, unsigned int, LPCWSTR );
+extern BOOL MSI_RecordIsNull( MSIRECORD *, unsigned int );
+extern UINT MSI_RecordGetStringW( MSIRECORD * , unsigned int, LPWSTR, DWORD *);
+extern UINT MSI_RecordGetStringA( MSIRECORD *, unsigned int, LPSTR, DWORD *);
+extern int MSI_RecordGetInteger( MSIRECORD *, unsigned int );
+extern UINT MSI_RecordReadStream( MSIRECORD *, unsigned int, char *, DWORD *);
+extern unsigned int MSI_RecordGetFieldCount( MSIRECORD *rec );
+
+/* stream internals */
+extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
+extern UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm );
+extern void enum_stream_names( IStorage *stg );
+
+/* database internals */
+extern UINT MSI_OpenDatabaseW( LPCWSTR, LPCWSTR, MSIDATABASE ** );
+extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** );
+
+/* view internals */
+extern UINT MSI_ViewExecute( MSIQUERY*, MSIRECORD * );
+extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** );
+extern UINT MSI_ViewClose( MSIQUERY* );
+
+/* package internals */
+extern UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE ** );
+extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR);
+extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD* );
+extern UINT MSI_GetPropertyW( MSIPACKAGE *, LPCWSTR, LPWSTR, DWORD*);
+extern MSICONDITION MSI_EvaluateConditionW( MSIPACKAGE *, LPCWSTR );
+extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
+extern UINT MSI_GetComponentStateW(MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE *);
+extern UINT MSI_GetFeatureStateW(MSIPACKAGE *, LPWSTR, INSTALLSTATE *, INSTALLSTATE *);
+
+/* registry data encoding/decoding functions */
+BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
+BOOL squash_guid(LPCWSTR in, LPWSTR out);
+BOOL encode_base85_guid(GUID *,LPWSTR);
+BOOL decode_base85_guid(LPCWSTR,GUID*);
+
+/* UI globals */
+extern INSTALLUILEVEL gUILevel;
+extern HWND gUIhwnd;
+extern INSTALLUI_HANDLERA gUIHandler;
+extern DWORD gUIFilter;
+extern LPVOID gUIContext;
+extern WCHAR gszLogFile[MAX_PATH];
+
+#endif /* __WINE_MSI_PRIVATE__ */
reactos/lib/msi
diff -N msiquery.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ msiquery.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,485 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+#if 0
+typedef struct tagMSIQUERY
+{
+ MSIOBJECTHDR hdr;
+ MSIVIEW *view;
+ UINT row;
+ MSIDATABASE *db;
+} MSIQUERY;
+#endif
+
+UINT WINAPI MsiDatabaseIsTablePersistentA(
+ MSIHANDLE hDatabase, LPSTR szTableName)
+{
+ FIXME("%lx %s\n", hDatabase, debugstr_a(szTableName));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseIsTablePersistentW(
+ MSIHANDLE hDatabase, LPWSTR szTableName)
+{
+ FIXME("%lx %s\n", hDatabase, debugstr_w(szTableName));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+void MSI_CloseView( MSIOBJECTHDR *arg )
+{
+ MSIQUERY *query = (MSIQUERY*) arg;
+
+ if( query->view && query->view->ops->delete )
+ query->view->ops->delete( query->view );
+ msiobj_release( &query->db->hdr );
+}
+
+UINT VIEW_find_column( MSIVIEW *table, LPWSTR name, UINT *n )
+{
+ LPWSTR col_name;
+ UINT i, count, r;
+
+ r = table->ops->get_dimensions( table, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ for( i=1; i<=count; i++ )
+ {
+ INT x;
+
+ col_name = NULL;
+ r = table->ops->get_column_info( table, i, &col_name, NULL );
+ if( r != ERROR_SUCCESS )
+ return r;
+ x = lstrcmpW( name, col_name );
+ HeapFree( GetProcessHeap(), 0, col_name );
+ if( !x )
+ {
+ *n = i;
+ return ERROR_SUCCESS;
+ }
+ }
+
+ return ERROR_INVALID_PARAMETER;
+}
+
+UINT WINAPI MsiDatabaseOpenViewA(MSIHANDLE hdb,
+ LPCSTR szQuery, MSIHANDLE *phView)
+{
+ UINT r;
+ LPWSTR szwQuery;
+
+ TRACE("%ld %s %p\n", hdb, debugstr_a(szQuery), phView);
+
+ if( szQuery )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szQuery, -1, NULL, 0 );
+ szwQuery = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+ if( !szwQuery )
+ return ERROR_FUNCTION_FAILED;
+ MultiByteToWideChar( CP_ACP, 0, szQuery, -1, szwQuery, len );
+ }
+ else
+ szwQuery = NULL;
+
+ r = MsiDatabaseOpenViewW( hdb, szwQuery, phView);
+
+ return r;
+}
+
+UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
+ LPCWSTR szQuery, MSIQUERY **pView)
+{
+ MSIQUERY *query;
+ UINT r;
+
+ TRACE("%s %p\n", debugstr_w(szQuery), pView);
+
+ if( !szQuery)
+ return ERROR_INVALID_PARAMETER;
+
+ /* pre allocate a handle to hold a pointer to the view */
+ query = alloc_msiobject( MSIHANDLETYPE_VIEW, sizeof (MSIQUERY),
+ MSI_CloseView );
+ if( !query )
+ return ERROR_FUNCTION_FAILED;
+
+ msiobj_addref( &db->hdr );
+ query->row = 0;
+ query->db = db;
+ query->view = NULL;
+
+ r = MSI_ParseSQL( db, szQuery, &query->view );
+ if( r == ERROR_SUCCESS )
+ {
+ msiobj_addref( &query->hdr );
+ *pView = query;
+ }
+
+ msiobj_release( &query->hdr );
+ return r;
+}
+
+UINT WINAPI MsiDatabaseOpenViewW(MSIHANDLE hdb,
+ LPCWSTR szQuery, MSIHANDLE *phView)
+{
+ MSIDATABASE *db;
+ MSIQUERY *query = NULL;
+ UINT ret;
+
+ TRACE("%s %p\n", debugstr_w(szQuery), phView);
+
+ db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
+ if( !db )
+ return ERROR_INVALID_HANDLE;
+
+ ret = MSI_DatabaseOpenViewW( db, szQuery, &query );
+ if( ret == ERROR_SUCCESS )
+ {
+ *phView = alloc_msihandle( &query->hdr );
+ msiobj_release( &query->hdr );
+ }
+ msiobj_release( &db->hdr );
+
+ return ret;
+}
+
+UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
+{
+ MSIVIEW *view;
+ MSIRECORD *rec;
+ UINT row_count = 0, col_count = 0, i, ival, ret, type;
+
+ TRACE("%p %p\n", query, prec );
+
+ view = query->view;
+ if( !view )
+ return ERROR_FUNCTION_FAILED;
+
+ ret = view->ops->get_dimensions( view, &row_count, &col_count );
+ if( ret )
+ return ret;
+ if( !col_count )
+ return ERROR_INVALID_PARAMETER;
+
+ if( query->row >= row_count )
+ return ERROR_NO_MORE_ITEMS;
+
+ rec = MSI_CreateRecord( col_count );
+ if( !rec )
+ return ERROR_FUNCTION_FAILED;
+
+ for( i=1; i<=col_count; i++ )
+ {
+ ret = view->ops->get_column_info( view, i, NULL, &type );
+ if( ret )
+ {
+ ERR("Error getting column type for %d\n", i );
+ continue;
+ }
+ if (( type != MSITYPE_BINARY) && (type != (MSITYPE_BINARY |
+ MSITYPE_NULLABLE)))
+ {
+ ret = view->ops->fetch_int( view, query->row, i, &ival );
+ if( ret )
+ {
+ ERR("Error fetching data for %d\n", i );
+ continue;
+ }
+ if( ! (type & MSITYPE_VALID ) )
+ ERR("Invalid type!\n");
+
+ /* check if it's nul (0) - if so, don't set anything */
+ if( !ival )
+ continue;
+
+ if( type & MSITYPE_STRING )
+ {
+ LPWSTR sval;
+
+ sval = MSI_makestring( query->db, ival );
+ MSI_RecordSetStringW( rec, i, sval );
+ HeapFree( GetProcessHeap(), 0, sval );
+ }
+ else
+ {
+ if( (type & MSI_DATASIZEMASK) == 2 )
+ MSI_RecordSetInteger( rec, i, ival - (1<<15) );
+ else
+ MSI_RecordSetInteger( rec, i, ival - (1<<31) );
+ }
+ }
+ else
+ {
+ IStream *stm = NULL;
+
+ ret = view->ops->fetch_stream( view, query->row, i, &stm );
+ if( ( ret == ERROR_SUCCESS ) && stm )
+ {
+ MSI_RecordSetIStream( rec, i, stm );
+ IStream_Release( stm );
+ }
+ else
+ ERR("failed to get stream\n");
+ }
+ }
+ query->row ++;
+
+ *prec = rec;
+
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
+{
+ MSIQUERY *query;
+ MSIRECORD *rec = NULL;
+ UINT ret;
+
+ TRACE("%ld %p\n", hView, record);
+
+ query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+ if( !query )
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_ViewFetch( query, &rec );
+ if( ret == ERROR_SUCCESS )
+ {
+ *record = alloc_msihandle( &rec->hdr );
+ msiobj_release( &rec->hdr );
+ }
+ msiobj_release( &query->hdr );
+ return ret;
+}
+
+UINT MSI_ViewClose(MSIQUERY *query)
+{
+ MSIVIEW *view;
+
+ TRACE("%p\n", query );
+
+ view = query->view;
+ if( !view )
+ return ERROR_FUNCTION_FAILED;
+ if( !view->ops->close )
+ return ERROR_FUNCTION_FAILED;
+
+ return view->ops->close( view );
+}
+
+UINT WINAPI MsiViewClose(MSIHANDLE hView)
+{
+ MSIQUERY *query;
+ UINT ret;
+
+ TRACE("%ld\n", hView );
+
+ query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+ if( !query )
+ return ERROR_INVALID_HANDLE;
+
+ ret = MSI_ViewClose( query );
+ msiobj_release( &query->hdr );
+ return ret;
+}
+
+UINT MSI_ViewExecute(MSIQUERY *query, MSIRECORD *rec )
+{
+ MSIVIEW *view;
+
+ TRACE("%p %p\n", query, rec);
+
+ view = query->view;
+ if( !view )
+ return ERROR_FUNCTION_FAILED;
+ if( !view->ops->execute )
+ return ERROR_FUNCTION_FAILED;
+ query->row = 0;
+
+ return view->ops->execute( view, rec );
+}
+
+UINT WINAPI MsiViewExecute(MSIHANDLE hView, MSIHANDLE hRec)
+{
+ MSIQUERY *query;
+ MSIRECORD *rec = NULL;
+ UINT ret;
+
+ TRACE("%ld %ld\n", hView, hRec);
+
+ query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+ if( !query )
+ return ERROR_INVALID_HANDLE;
+
+ if( hRec )
+ {
+ rec = msihandle2msiinfo( hRec, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ {
+ ret = ERROR_INVALID_HANDLE;
+ goto out;
+ }
+ }
+
+ ret = MSI_ViewExecute( query, rec );
+out:
+ if( query )
+ msiobj_release( &query->hdr );
+ if( rec )
+ msiobj_release( &rec->hdr );
+
+ return ret;
+}
+
+UINT WINAPI MsiViewGetColumnInfo(MSIHANDLE hView, MSICOLINFO info, MSIHANDLE *hRec)
+{
+ MSIVIEW *view;
+ MSIQUERY *query;
+ MSIHANDLE handle;
+ UINT ret, i, count = 0, type;
+ LPWSTR name;
+
+ TRACE("%ld %d %p\n", hView, info, hRec);
+
+ query = msihandle2msiinfo( hView, MSIHANDLETYPE_VIEW );
+ if( !query )
+ return ERROR_INVALID_HANDLE;
+
+ view = query->view;
+ if( !view )
+ return ERROR_FUNCTION_FAILED;
+
+ if( !view->ops->get_dimensions )
+ return ERROR_FUNCTION_FAILED;
+
+ ret = view->ops->get_dimensions( view, NULL, &count );
+ if( ret )
+ return ret;
+ if( !count )
+ return ERROR_INVALID_PARAMETER;
+
+ handle = MsiCreateRecord( count );
+ if( !handle )
+ return ERROR_FUNCTION_FAILED;
+
+ for( i=0; i<count; i++ )
+ {
+ name = NULL;
+ ret = view->ops->get_column_info( view, i+1, &name, &type );
+ if( ret != ERROR_SUCCESS )
+ continue;
+ MsiRecordSetStringW( handle, i+1, name );
+ HeapFree( GetProcessHeap(), 0, name );
+ }
+
+ *hRec = handle;
+
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiDatabaseApplyTransformA( MSIHANDLE hdb,
+ LPCSTR szTransformFile, int iErrorCond)
+{
+ FIXME("%ld %s %d\n", hdb, debugstr_a(szTransformFile), iErrorCond);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseApplyTransformW( MSIHANDLE hdb,
+ LPCWSTR szTransformFile, int iErrorCond)
+{
+ FIXME("%ld %s %d\n", hdb, debugstr_w(szTransformFile), iErrorCond);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseGenerateTransformA( MSIHANDLE hdb, MSIHANDLE hdbref,
+ LPCSTR szTransformFile, int iReserved1, int iReserved2 )
+{
+ FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
+ debugstr_a(szTransformFile), iReserved1, iReserved2);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseGenerateTransformW( MSIHANDLE hdb, MSIHANDLE hdbref,
+ LPCWSTR szTransformFile, int iReserved1, int iReserved2 )
+{
+ FIXME("%ld %ld %s %d %d\n", hdb, hdbref,
+ debugstr_w(szTransformFile), iReserved1, iReserved2);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
+{
+ MSIDATABASE *db;
+ UINT r;
+
+ TRACE("%ld\n", hdb);
+
+ db = msihandle2msiinfo( hdb, MSIHANDLETYPE_DATABASE );
+ if( !db )
+ return ERROR_INVALID_HANDLE;
+
+ /* FIXME: lock the database */
+
+ r = MSI_CommitTables( db );
+
+ /* FIXME: unlock the database */
+
+ return r;
+}
+
+UINT WINAPI MsiDatabaseGetPrimaryKeysA(MSIHANDLE hdb,
+ LPCSTR table, MSIHANDLE* rec)
+{
+ FIXME("%ld %s %p\n", hdb, debugstr_a(table), rec);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiDatabaseGetPrimaryKeysW(MSIHANDLE hdb,
+ LPCWSTR table, MSIHANDLE* rec)
+{
+ FIXME("%ld %s %p\n", hdb, debugstr_w(table), rec);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiViewModify(MSIHANDLE hView, MSIMODIFY eModifyMode, MSIHANDLE
+hRecord)
+{
+ FIXME("%ld %x %ld\n",hView, eModifyMode, hRecord);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
reactos/lib/msi
diff -N order.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ order.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,335 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIORDERVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ MSIVIEW *table;
+ UINT *reorder;
+ UINT num_cols;
+ UINT cols[1];
+} MSIORDERVIEW;
+
+static UINT ORDER_compare( MSIORDERVIEW *ov, UINT a, UINT b, UINT *swap )
+{
+ UINT r, i, a_val = 0, b_val = 0;
+
+ *swap = 0;
+ for( i=0; i<ov->num_cols; i++ )
+ {
+ r = ov->table->ops->fetch_int( ov->table, a, ov->cols[i], &a_val );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = ov->table->ops->fetch_int( ov->table, b, ov->cols[i], &b_val );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ if( a_val != b_val )
+ {
+ if( a_val > b_val )
+ *swap = 1;
+ break;
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ORDER_mergesort( MSIORDERVIEW *ov, UINT left, UINT right )
+{
+ UINT r, centre = (left + right)/2, temp, swap = 0, i, j;
+ UINT *array = ov->reorder;
+
+ if( left == right )
+ return ERROR_SUCCESS;
+
+ /* sort the left half */
+ r = ORDER_mergesort( ov, left, centre );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* sort the right half */
+ r = ORDER_mergesort( ov, centre+1, right );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ for( i=left, j=centre+1; (i<=centre) && (j<=right); i++ )
+ {
+ r = ORDER_compare( ov, array[i], array[j], &swap );
+ if( r != ERROR_SUCCESS )
+ return r;
+ if( swap )
+ {
+ temp = array[j];
+ memmove( &array[i+1], &array[i], (j-i)*sizeof (UINT) );
+ array[i] = temp;
+ j++;
+ centre++;
+ }
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ORDER_verify( MSIORDERVIEW *ov, UINT num_rows )
+{
+ UINT i, swap, r;
+
+ for( i=1; i<num_rows; i++ )
+ {
+ r = ORDER_compare( ov, ov->reorder[i-1], ov->reorder[i], &swap );
+ if( r != ERROR_SUCCESS )
+ return r;
+ if( !swap )
+ continue;
+ ERR("Bad order! %d\n", i);
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ORDER_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+ TRACE("%p %d %d %p\n", ov, row, col, val );
+
+ if( !ov->table )
+ return ERROR_FUNCTION_FAILED;
+
+ row = ov->reorder[ row ];
+
+ return ov->table->ops->fetch_int( ov->table, row, col, val );
+}
+
+static UINT ORDER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+ UINT r, num_rows = 0, i;
+
+ TRACE("%p %p\n", ov, record);
+
+ if( !ov->table )
+ return ERROR_FUNCTION_FAILED;
+
+ r = ov->table->ops->execute( ov->table, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = ov->table->ops->get_dimensions( ov->table, &num_rows, NULL );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ ov->reorder = HeapAlloc( GetProcessHeap(), 0, num_rows*sizeof(UINT) );
+ if( !ov->reorder )
+ return ERROR_FUNCTION_FAILED;
+
+ for( i=0; i<num_rows; i++ )
+ ov->reorder[i] = i;
+
+ r = ORDER_mergesort( ov, 0, num_rows - 1 );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = ORDER_verify( ov, num_rows );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ORDER_close( struct tagMSIVIEW *view )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+ TRACE("%p\n", ov );
+
+ if( !ov->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( ov->reorder )
+ HeapFree( GetProcessHeap(), 0, ov->reorder );
+ ov->reorder = NULL;
+
+ return ov->table->ops->close( ov->table );
+}
+
+static UINT ORDER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+ TRACE("%p %p %p\n", ov, rows, cols );
+
+ if( !ov->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return ov->table->ops->get_dimensions( ov->table, rows, cols );
+}
+
+static UINT ORDER_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+ TRACE("%p %d %p %p\n", ov, n, name, type );
+
+ if( !ov->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return ov->table->ops->get_column_info( ov->table, n, name, type );
+}
+
+static UINT ORDER_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+ TRACE("%p %d %ld\n", ov, eModifyMode, hrec );
+
+ if( !ov->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return ov->table->ops->modify( ov->table, eModifyMode, hrec );
+}
+
+static UINT ORDER_delete( struct tagMSIVIEW *view )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+
+ TRACE("%p\n", ov );
+
+ if( ov->table )
+ ov->table->ops->delete( ov->table );
+
+ if( ov->reorder )
+ HeapFree( GetProcessHeap(), 0, ov->reorder );
+ ov->reorder = NULL;
+
+ msiobj_release( &ov->db->hdr );
+ HeapFree( GetProcessHeap(), 0, ov );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS order_ops =
+{
+ ORDER_fetch_int,
+ NULL,
+ NULL,
+ NULL,
+ ORDER_execute,
+ ORDER_close,
+ ORDER_get_dimensions,
+ ORDER_get_column_info,
+ ORDER_modify,
+ ORDER_delete
+};
+
+UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table )
+{
+ MSIORDERVIEW *ov = NULL;
+ UINT count = 0, r;
+
+ TRACE("%p\n", ov );
+
+ r = table->ops->get_dimensions( table, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("can't get table dimensions\n");
+ return r;
+ }
+
+ ov = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof *ov + sizeof (UINT) * count );
+ if( !ov )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ ov->view.ops = &order_ops;
+ msiobj_addref( &db->hdr );
+ ov->db = db;
+ ov->table = table;
+ ov->reorder = NULL;
+ ov->num_cols = 0;
+ *view = (MSIVIEW*) ov;
+
+ return ERROR_SUCCESS;
+}
+
+UINT ORDER_AddColumn( MSIVIEW *view, LPWSTR name )
+{
+ MSIORDERVIEW *ov = (MSIORDERVIEW*)view;
+ UINT n, count, r;
+ MSIVIEW *table;
+
+ TRACE("%p adding %s\n", ov, debugstr_w( name ) );
+
+ if( ov->view.ops != &order_ops )
+ return ERROR_FUNCTION_FAILED;
+
+ table = ov->table;
+ if( !table )
+ return ERROR_FUNCTION_FAILED;
+ if( !table->ops->get_dimensions )
+ return ERROR_FUNCTION_FAILED;
+ if( !table->ops->get_column_info )
+ return ERROR_FUNCTION_FAILED;
+
+ r = table->ops->get_dimensions( table, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ if( ov->num_cols >= count )
+ return ERROR_FUNCTION_FAILED;
+
+ r = VIEW_find_column( table, name, &n );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ ov->cols[ov->num_cols] = n;
+ TRACE("Ordering by column %s (%d)\n", debugstr_w( name ), n);
+
+ ov->num_cols++;
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N package.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ package.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,843 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Aric Stewart for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define NONAMELESSUNION
+
+#include <stdarg.h>
+#include <stdio.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "wincrypt.h"
+#include "winuser.h"
+#include "shlobj.h"
+#include "wine/unicode.h"
+#include "objbase.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
+ * which is a problem because LPCTSTR isn't defined when compiling wine.
+ * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
+ * and make sure to only use it in W functions.
+ */
+#define LPCTSTR LPCWSTR
+
+void MSI_FreePackage( MSIOBJECTHDR *arg)
+{
+ MSIPACKAGE *package= (MSIPACKAGE*) arg;
+
+ ACTION_remove_tracked_tempfiles(package);
+
+ if (package->features && package->loaded_features > 0)
+ HeapFree(GetProcessHeap(),0,package->features);
+
+ if (package->folders && package->loaded_folders > 0)
+ HeapFree(GetProcessHeap(),0,package->folders);
+
+ if (package->components && package->loaded_components > 0)
+ HeapFree(GetProcessHeap(),0,package->components);
+
+ if (package->files && package->loaded_files > 0)
+ HeapFree(GetProcessHeap(),0,package->files);
+ msiobj_release( &package->db->hdr );
+}
+
+UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
+{
+ LPWSTR szwPack = NULL;
+ UINT len, ret;
+
+ TRACE("%s %p\n",debugstr_a(szPackage), phPackage);
+
+ if( szPackage )
+ {
+ len = MultiByteToWideChar( CP_ACP, 0, szPackage, -1, NULL, 0 );
+ szwPack = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
+ if( szwPack )
+ MultiByteToWideChar( CP_ACP, 0, szPackage, -1, szwPack, len );
+ }
+
+ ret = MsiOpenPackageW( szwPack, phPackage );
+
+ if( szwPack )
+ HeapFree( GetProcessHeap(), 0, szwPack );
+
+ return ret;
+}
+
+
+static const UINT clone_properties(MSIDATABASE *db)
+{
+ MSIQUERY * view = NULL;
+ UINT rc;
+ static const WCHAR CreateSql[] = {
+ 'C','R','E','A','T','E',' ','T','A','B','L','E',' ','`','_','P','r','o',
+ 'p','e','r','t','y','`',' ','(',' ','`','_','P','r','o','p','e','r','t',
+ 'y','`',' ','C','H','A','R','(','5','6',')',' ','N','O','T',' ','N','U',
+ 'L','L',',',' ','`','V','a','l','u','e','`',' ','C','H','A','R','(','9',
+ '8',')',' ','N','O','T',' ','N','U','L','L',' ','P','R','I','M','A','R',
+ 'Y',' ','K','E','Y',' ','`','_','P','r','o','p','e','r','t','y','`',')',0};
+ static const WCHAR Query[] = {
+ 'S','E','L','E','C','T',' ','*',' ',
+ 'f','r','o','m',' ','P','r','o','p','e','r','t','y',0};
+ static const WCHAR Insert[] = {
+ 'I','N','S','E','R','T',' ','i','n','t','o',' ',
+ '`','_','P','r','o','p','e','r','t','y','`',' ',
+ '(','`','_','P','r','o','p','e','r','t','y','`',',',
+ '`','V','a','l','u','e','`',')',' ',
+ 'V','A','L','U','E','S',' ','(','?',')',0};
+
+ /* create the temporary properties table */
+ rc = MSI_DatabaseOpenViewW(db, CreateSql, &view);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+ rc = MSI_ViewExecute(view,0);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
+ /* clone the existing properties */
+ rc = MSI_DatabaseOpenViewW(db, Query, &view);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+
+ rc = MSI_ViewExecute(view, 0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return rc;
+ }
+ while (1)
+ {
+ MSIRECORD * row;
+ MSIQUERY * view2;
+
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ break;
+
+ rc = MSI_DatabaseOpenViewW(db,Insert,&view2);
+ if (rc!= ERROR_SUCCESS)
+ continue;
+ rc = MSI_ViewExecute(view2,row);
+ MSI_ViewClose(view2);
+ msiobj_release(&view2->hdr);
+
+ if (rc == ERROR_SUCCESS)
+ msiobj_release(&row->hdr);
+ }
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+
+ return rc;
+}
+
+/*
+ * There are a whole slew of these we need to set
+ *
+ *
+http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/properties.asp
+ */
+static VOID set_installer_properties(MSIPACKAGE *package)
+{
+ WCHAR pth[MAX_PATH];
+ OSVERSIONINFOA OSVersion;
+ DWORD verval;
+ WCHAR verstr[10], msiver[10];
+
+ static const WCHAR cszbs[]={'\\',0};
+ static const WCHAR CFF[] =
+{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
+ static const WCHAR PFF[] =
+{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
+ static const WCHAR CADF[] =
+{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR FaF[] =
+{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
+ static const WCHAR FoF[] =
+{'F','o','n','t','s','F','o','l','d','e','r',0};
+ static const WCHAR SendTF[] =
+{'S','e','n','d','T','o','F','o','l','d','e','r',0};
+ static const WCHAR SMF[] =
+{'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
+ static const WCHAR StF[] =
+{'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
+ static const WCHAR TemplF[] =
+{'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
+ static const WCHAR DF[] =
+{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
+ static const WCHAR PMF[] =
+{'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
+ static const WCHAR ATF[] =
+{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
+ static const WCHAR ADF[] =
+{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR SF[] =
+{'S','y','s','t','e','m','F','o','l','d','e','r',0};
+ static const WCHAR LADF[] =
+{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR MPF[] =
+{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
+ static const WCHAR PF[] =
+{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
+ static const WCHAR WF[] =
+{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+ static const WCHAR TF[]=
+{'T','e','m','p','F','o','l','d','e','r',0};
+ static const WCHAR szAdminUser[] =
+{'A','d','m','i','n','U','s','e','r',0};
+ static const WCHAR szPriv[] =
+{'P','r','i','v','i','l','e','g','e','d',0};
+ static const WCHAR szOne[] =
+{'1',0};
+ static const WCHAR v9x[] = { 'V','e','r','s','i','o','n','9','X',0 };
+ static const WCHAR vNT[] = { 'V','e','r','s','i','o','n','N','T',0 };
+ static const WCHAR szFormat[] = {'%','l','i',0};
+ static const WCHAR szWinBuild[] =
+{'W','i','n','d','o','w','s','B','u','i','l','d', 0 };
+ static const WCHAR szSPL[] =
+{'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0 };
+ static const WCHAR szSix[] = {'6',0 };
+
+ static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
+ static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
+
+/*
+ * Other things I notice set
+ *
+ScreenY
+ScreenX
+SystemLanguageID
+ComputerName
+UserLanguageID
+LogonUser
+VirtualMemory
+PhysicalMemory
+Intel
+ShellAdvSupport
+DefaultUIFont
+VersionDatabase
+PackagecodeChanging
+ProductState
+CaptionHeight
+BorderTop
+BorderSide
+TextHeight
+ColorBits
+RedirectedDllSupport
+Time
+Date
+Privileged
+*/
+
+ SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, CFF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, PFF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, CADF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_FAVORITES,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, FaF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_FONTS,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, FoF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_SENDTO,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, SendTF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_STARTMENU,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, SMF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_STARTUP,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, StF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_TEMPLATES,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, TemplF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_DESKTOP,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, DF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_PROGRAMS,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, PMF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, ATF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, ADF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, SF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, LADF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, MPF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, PF, pth);
+
+ SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
+ strcatW(pth,cszbs);
+ MSI_SetPropertyW(package, WF, pth);
+
+ GetTempPathW(MAX_PATH,pth);
+ MSI_SetPropertyW(package, TF, pth);
+
+
+ /* in a wine environment the user is always admin and privileged */
+ MSI_SetPropertyW(package,szAdminUser,szOne);
+ MSI_SetPropertyW(package,szPriv,szOne);
+
+ /* set the os things */
+ OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+ GetVersionExA(&OSVersion);
+ verval = OSVersion.dwMinorVersion+OSVersion.dwMajorVersion*100;
+ sprintfW(verstr,szFormat,verval);
+ switch (OSVersion.dwPlatformId)
+ {
+ case VER_PLATFORM_WIN32_WINDOWS:
+ MSI_SetPropertyW(package,v9x,verstr);
+ break;
+ case VER_PLATFORM_WIN32_NT:
+ MSI_SetPropertyW(package,vNT,verstr);
+ break;
+ }
+ sprintfW(verstr,szFormat,OSVersion.dwBuildNumber);
+ MSI_SetPropertyW(package,szWinBuild,verstr);
+ /* just fudge this */
+ MSI_SetPropertyW(package,szSPL,szSix);
+
+ sprintfW( msiver, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
+ MSI_SetPropertyW( package, szVersionMsi, msiver );
+}
+
+UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
+{
+ UINT rc;
+ MSIDATABASE *db = NULL;
+ MSIPACKAGE *package = NULL;
+ WCHAR uilevel[10];
+ UINT ret = ERROR_FUNCTION_FAILED;
+
+ static const WCHAR OriginalDatabase[] =
+{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
+ static const WCHAR Database[] =
+{'D','A','T','A','B','A','S','E',0};
+ static const WCHAR szpi[] = {'%','i',0};
+ static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 };
+
+ TRACE("%s %p\n",debugstr_w(szPackage), pPackage);
+
+ if (szPackage[0] == '#')
+ {
+ INT handle = atoiW(&szPackage[1]);
+ db = msihandle2msiinfo( handle , MSIHANDLETYPE_DATABASE);
+ }
+ else
+ {
+ rc = MSI_OpenDatabaseW(szPackage, MSIDBOPEN_READONLY, &db);
+ if (rc != ERROR_SUCCESS)
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
+ MSI_FreePackage );
+
+ if (package)
+ {
+ msiobj_addref( &db->hdr );
+
+ package->db = db;
+ package->features = NULL;
+ package->folders = NULL;
+ package->components = NULL;
+ package->files = NULL;
+ package->loaded_features = 0;
+ package->loaded_folders = 0;
+ package->loaded_components= 0;
+ package->loaded_files = 0;
+
+ /* OK, here is where we do a slew of things to the database to
+ * prep for all that is to come as a package */
+
+ clone_properties(db);
+ set_installer_properties(package);
+ MSI_SetPropertyW(package, OriginalDatabase, szPackage);
+ MSI_SetPropertyW(package, Database, szPackage);
+ sprintfW(uilevel,szpi,gUILevel);
+ MSI_SetPropertyW(package, szLevel, uilevel);
+
+ msiobj_addref( &package->hdr );
+ *pPackage = package;
+ ret = ERROR_SUCCESS;
+ }
+
+ if( package )
+ msiobj_release( &package->hdr );
+ if( db )
+ msiobj_release( &db->hdr );
+
+ return ret;
+}
+
+UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
+{
+ MSIPACKAGE *package = NULL;
+ UINT ret;
+
+ ret = MSI_OpenPackageW( szPackage, &package);
+ if( ret == ERROR_SUCCESS )
+ {
+ *phPackage = alloc_msihandle( &package->hdr );
+ msiobj_release( &package->hdr );
+ }
+ return ret;
+}
+
+UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
+{
+ FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
+{
+ FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
+{
+ MSIPACKAGE *package;
+ MSIHANDLE handle = 0;
+
+ TRACE("(%ld)\n",hInstall);
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if( package)
+ {
+ handle = alloc_msihandle( &package->db->hdr );
+ msiobj_release( &package->hdr );
+ }
+
+ return handle;
+}
+
+INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
+ MSIRECORD *record)
+{
+ DWORD log_type = 0;
+ LPWSTR message;
+ DWORD sz;
+ DWORD total_size = 0;
+ INT msg_field=1;
+ INT i;
+ INT rc;
+ char *msg;
+ int len;
+
+ TRACE("%x \n",eMessageType);
+ rc = 0;
+
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ERROR)
+ log_type |= INSTALLLOGMODE_ERROR;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_WARNING)
+ log_type |= INSTALLLOGMODE_WARNING;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_USER)
+ log_type |= INSTALLLOGMODE_USER;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_INFO)
+ log_type |= INSTALLLOGMODE_INFO;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_COMMONDATA)
+ log_type |= INSTALLLOGMODE_COMMONDATA;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONSTART)
+ log_type |= INSTALLLOGMODE_ACTIONSTART;
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA)
+ log_type |= INSTALLLOGMODE_ACTIONDATA;
+ /* just a guess */
+ if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
+ log_type |= 0x800;
+
+ message = HeapAlloc(GetProcessHeap(),0,1*sizeof (WCHAR));
+ message[0]=0;
+ msg_field = MSI_RecordGetFieldCount(record);
+ for (i = 1; i <= msg_field; i++)
+ {
+ LPWSTR tmp;
+ WCHAR number[3];
+ const static WCHAR format[] = { '%','i',':',' ',0};
+ const static WCHAR space[] = { ' ',0};
+ sz = 0;
+ MSI_RecordGetStringW(record,i,NULL,&sz);
+ sz+=4;
+ total_size+=sz*sizeof(WCHAR);
+ tmp = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
+ message = HeapReAlloc(GetProcessHeap(),0,message,total_size*sizeof (WCHAR));
+
+ MSI_RecordGetStringW(record,i,tmp,&sz);
+
+ if (msg_field > 1)
+ {
+ sprintfW(number,format,i);
+ strcatW(message,number);
+ }
+ strcatW(message,tmp);
+ if (msg_field > 1)
+ strcatW(message,space);
+
+ HeapFree(GetProcessHeap(),0,tmp);
+ }
+
+ TRACE("(%p %lx %lx %s)\n",gUIHandler, gUIFilter, log_type,
+ debugstr_w(message));
+
+ /* convert it to ASCII */
+ len = WideCharToMultiByte( CP_ACP, 0, message, -1,
+ NULL, 0, NULL, NULL );
+ msg = HeapAlloc( GetProcessHeap(), 0, len );
+ WideCharToMultiByte( CP_ACP, 0, message, -1,
+ msg, len, NULL, NULL );
+
+ if (gUIHandler && (gUIFilter & log_type))
+ {
+ rc = gUIHandler(gUIContext,eMessageType,msg);
+ }
+
+ if ((!rc) && (gszLogFile[0]) && !((eMessageType & 0xff000000) ==
+ INSTALLMESSAGE_PROGRESS))
+ {
+ DWORD write;
+ HANDLE log_file = CreateFileW(gszLogFile,GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ if (log_file != INVALID_HANDLE_VALUE)
+ {
+ SetFilePointer(log_file,0, NULL, FILE_END);
+ WriteFile(log_file,msg,strlen(msg),&write,NULL);
+ WriteFile(log_file,"\n",1,&write,NULL);
+ CloseHandle(log_file);
+ }
+ }
+ HeapFree( GetProcessHeap(), 0, msg );
+
+ HeapFree(GetProcessHeap(),0,message);
+ return ERROR_SUCCESS;
+}
+
+INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
+ MSIHANDLE hRecord)
+{
+ UINT ret = ERROR_INVALID_HANDLE;
+ MSIPACKAGE *package = NULL;
+ MSIRECORD *record = NULL;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
+ if( !package )
+ goto out;
+
+ record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );
+ if( !record )
+ goto out;
+
+ ret = MSI_ProcessMessage( package, eMessageType, record );
+
+out:
+ if( package )
+ msiobj_release( &package->hdr );
+ if( record )
+ msiobj_release( &record->hdr );
+
+ return ret;
+}
+
+/* property code */
+UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue)
+{
+ LPWSTR szwName = NULL, szwValue = NULL;
+ UINT hr = ERROR_INSTALL_FAILURE;
+ UINT len;
+
+ if (0 == hInstall) {
+ return ERROR_INVALID_HANDLE;
+ }
+ if (NULL == szName) {
+ return ERROR_INVALID_PARAMETER;
+ }
+ if (NULL == szValue) {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
+ szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwName )
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
+
+ len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
+ szwValue = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if( !szwValue)
+ goto end;
+ MultiByteToWideChar( CP_ACP, 0, szValue , -1, szwValue, len );
+
+ hr = MsiSetPropertyW( hInstall, szwName, szwValue);
+
+end:
+ if( szwName )
+ HeapFree( GetProcessHeap(), 0, szwName );
+ if( szwValue )
+ HeapFree( GetProcessHeap(), 0, szwValue );
+
+ return hr;
+}
+
+UINT MSI_SetPropertyW( MSIPACKAGE *package, LPCWSTR szName, LPCWSTR szValue)
+{
+ MSIQUERY *view;
+ MSIRECORD *row;
+ UINT rc;
+ DWORD sz = 0;
+ static const WCHAR Insert[]=
+ {'I','N','S','E','R','T',' ','i','n','t','o',' ','`','_','P','r','o','p'
+,'e','r','t','y','`',' ','(','`','_','P','r','o','p','e','r','t','y','`'
+,',','`','V','a','l','u','e','`',')',' ','V','A','L','U','E','S'
+,' ','(','?',')',0};
+ static const WCHAR Update[]=
+ {'U','P','D','A','T','E',' ','_','P','r','o','p','e'
+,'r','t','y',' ','s','e','t',' ','`','V','a','l','u','e','`',' ','='
+,' ','?',' ','w','h','e','r','e',' ','`','_','P','r','o','p'
+,'e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
+ WCHAR Query[1024];
+
+ TRACE("Setting property (%s %s)\n",debugstr_w(szName),
+ debugstr_w(szValue));
+
+ rc = MSI_GetPropertyW(package,szName,0,&sz);
+ if (rc==ERROR_MORE_DATA || rc == ERROR_SUCCESS)
+ {
+ sprintfW(Query,Update,szName);
+
+ row = MSI_CreateRecord(1);
+ MSI_RecordSetStringW(row,1,szValue);
+
+ }
+ else
+ {
+ strcpyW(Query,Insert);
+
+ row = MSI_CreateRecord(2);
+ MSI_RecordSetStringW(row,1,szName);
+ MSI_RecordSetStringW(row,2,szValue);
+ }
+
+
+ rc = MSI_DatabaseOpenViewW(package->db,Query,&view);
+ if (rc!= ERROR_SUCCESS)
+ {
+ msiobj_release(&row->hdr);
+ return rc;
+ }
+
+ rc = MSI_ViewExecute(view,row);
+
+ msiobj_release(&row->hdr);
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+
+ return rc;
+}
+
+UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
+{
+ MSIPACKAGE *package;
+ UINT ret;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if( !package)
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_SetPropertyW( package, szName, szValue);
+ msiobj_release( &package->hdr );
+ return ret;
+}
+
+static UINT MSI_GetPropertyRow(MSIPACKAGE *package, LPCWSTR szName, MSIRECORD **row)
+{
+ MSIQUERY *view;
+ UINT rc, sz;
+ static const WCHAR select[]=
+ {'s','e','l','e','c','t',' ','V','a','l','u','e',' ','f','r','o','m',' '
+ ,'_','P','r','o','p','e','r','t','y',' ','w','h','e','r','e',' '
+ ,'_','P','r','o','p','e','r','t','y','=','`','%','s','`',0};
+ LPWSTR query;
+
+ if (!szName)
+ return ERROR_INVALID_PARAMETER;
+
+ sz = sizeof select + strlenW(szName)*sizeof(WCHAR);
+ query = HeapAlloc(GetProcessHeap(), 0, sz);
+ sprintfW(query,select,szName);
+
+ rc = MSI_DatabaseOpenViewW(package->db, query, &view);
+ HeapFree(GetProcessHeap(), 0, query);
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = MSI_ViewExecute(view, 0);
+ if (rc == ERROR_SUCCESS)
+ rc = MSI_ViewFetch(view,row);
+
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ }
+
+ return rc;
+}
+
+UINT MSI_GetPropertyW(MSIPACKAGE *package, LPCWSTR szName,
+ LPWSTR szValueBuf, DWORD* pchValueBuf)
+{
+ MSIRECORD *row;
+ UINT rc;
+
+ rc = MSI_GetPropertyRow(package, szName, &row);
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = MSI_RecordGetStringW(row,1,szValueBuf,pchValueBuf);
+ msiobj_release(&row->hdr);
+ }
+
+ if (rc == ERROR_SUCCESS)
+ TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
+ debugstr_w(szName));
+ else
+ {
+ *pchValueBuf = 0;
+ TRACE("property not found\n");
+ }
+
+ return rc;
+}
+
+UINT MSI_GetPropertyA(MSIPACKAGE *package, LPCSTR szName,
+ LPSTR szValueBuf, DWORD* pchValueBuf)
+{
+ MSIRECORD *row;
+ UINT rc, len;
+ LPWSTR szwName;
+
+ len = MultiByteToWideChar( CP_ACP, 0, szName, -1, NULL, 0 );
+ szwName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+ if (!szwName)
+ return ERROR_NOT_ENOUGH_MEMORY;
+ MultiByteToWideChar( CP_ACP, 0, szName, -1, szwName, len );
+
+ rc = MSI_GetPropertyRow(package, szwName, &row);
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = MSI_RecordGetStringA(row,1,szValueBuf,pchValueBuf);
+ msiobj_release(&row->hdr);
+ }
+
+ if (rc == ERROR_SUCCESS)
+ TRACE("returning %s for property %s\n", debugstr_a(szValueBuf),
+ debugstr_a(szName));
+ else
+ {
+ *pchValueBuf = 0;
+ TRACE("property not found\n");
+ }
+ HeapFree( GetProcessHeap(), 0, szwName );
+
+ return rc;
+}
+
+UINT WINAPI MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, LPSTR szValueBuf, DWORD* pchValueBuf)
+{
+ MSIPACKAGE *package;
+ UINT ret;
+
+ TRACE("%lu %s %lu\n", hInstall, debugstr_a(szName), *pchValueBuf);
+
+ if (0 == hInstall)
+ return ERROR_INVALID_HANDLE;
+ if (NULL == szName)
+ return ERROR_INVALID_PARAMETER;
+ if (NULL != szValueBuf && NULL == pchValueBuf)
+ return ERROR_INVALID_PARAMETER;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_GetPropertyA(package, szName, szValueBuf, pchValueBuf );
+ msiobj_release( &package->hdr );
+ return ret;
+}
+
+
+UINT WINAPI MsiGetPropertyW(MSIHANDLE hInstall, LPCWSTR szName,
+ LPWSTR szValueBuf, DWORD* pchValueBuf)
+{
+ MSIPACKAGE *package;
+ UINT ret;
+
+ if (0 == hInstall)
+ return ERROR_INVALID_HANDLE;
+ if (NULL == szName)
+ return ERROR_INVALID_PARAMETER;
+ if (NULL != szValueBuf && NULL == pchValueBuf)
+ return ERROR_INVALID_PARAMETER;
+
+ package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
+ if (!package)
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_GetPropertyW(package, szName, szValueBuf, pchValueBuf );
+ msiobj_release( &package->hdr );
+ return ret;
+}
reactos/lib/msi
diff -N query.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ query.h 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,139 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_MSI_QUERY_H
+#define __WINE_MSI_QUERY_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+
+#define OP_EQ 1
+#define OP_AND 2
+#define OP_OR 3
+#define OP_GT 4
+#define OP_LT 5
+#define OP_LE 6
+#define OP_GE 7
+#define OP_NE 8
+#define OP_ISNULL 9
+#define OP_NOTNULL 10
+
+#define EXPR_COMPLEX 1
+#define EXPR_COLUMN 2
+#define EXPR_COL_NUMBER 3
+#define EXPR_IVAL 4
+#define EXPR_SVAL 5
+#define EXPR_UVAL 6
+#define EXPR_STRCMP 7
+#define EXPR_UTF8 8
+#define EXPR_WILDCARD 9
+
+struct sql_str {
+ LPCWSTR data;
+ INT len;
+};
+
+typedef struct _string_list
+{
+ LPWSTR string;
+ struct _string_list *next;
+} string_list;
+
+struct complex_expr
+{
+ UINT op;
+ struct expr *left;
+ struct expr *right;
+};
+
+struct expr
+{
+ int type;
+ union
+ {
+ struct complex_expr expr;
+ INT ival;
+ UINT uval;
+ LPWSTR sval;
+ LPWSTR column;
+ UINT col_number;
+ char *utf8;
+ } u;
+};
+
+typedef struct _create_col_info
+{
+ LPWSTR colname;
+ UINT type;
+ struct _create_col_info *next;
+} create_col_info;
+
+typedef struct _value_list
+{
+ struct expr *val;
+ struct _value_list *next;
+} value_list;
+
+typedef struct _column_assignment
+{
+ string_list *col_list;
+ value_list *val_list;
+} column_assignment;
+
+
+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phView);
+
+UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view );
+
+UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+ string_list *columns );
+
+UINT DISTINCT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
+
+UINT ORDER_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
+UINT ORDER_AddColumn( MSIVIEW *group, LPWSTR name );
+
+UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+ struct expr *cond );
+
+UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+ create_col_info *col_info, BOOL temp );
+
+UINT INSERT_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+ string_list *columns, value_list *values, BOOL temp );
+
+UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **, LPWSTR table,
+ column_assignment *list, struct expr *expr );
+
+void delete_expr( struct expr *e );
+void delete_string_list( string_list *sl );
+void delete_value_list( value_list *vl );
+
+int sqliteGetToken(const WCHAR *z, int *tokenType);
+
+#endif /* __WINE_MSI_QUERY_H */
reactos/lib/msi
diff -N record.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ record.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,573 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+#define MSIFIELD_NULL 0
+#define MSIFIELD_INT 1
+#define MSIFIELD_STR 2
+#define MSIFIELD_WSTR 3
+#define MSIFIELD_STREAM 4
+
+void MSI_FreeField( MSIFIELD *field )
+{
+ switch( field->type )
+ {
+ case MSIFIELD_NULL:
+ case MSIFIELD_INT:
+ break;
+ case MSIFIELD_WSTR:
+ HeapFree( GetProcessHeap(), 0, field->u.szwVal);
+ break;
+ case MSIFIELD_STREAM:
+ IStream_Release( field->u.stream );
+ break;
+ default:
+ ERR("Invalid field type %d\n", field->type);
+ }
+}
+
+void MSI_CloseRecord( MSIOBJECTHDR *arg )
+{
+ MSIRECORD *rec = (MSIRECORD *) arg;
+ UINT i;
+
+ for( i=0; i<=rec->count; i++ )
+ MSI_FreeField( &rec->fields[i] );
+}
+
+MSIRECORD *MSI_CreateRecord( unsigned int cParams )
+{
+ MSIRECORD *rec;
+ UINT len;
+
+ TRACE("%d\n", cParams);
+
+ len = sizeof (MSIRECORD) + sizeof (MSIFIELD)*cParams;
+ rec = alloc_msiobject( MSIHANDLETYPE_RECORD, len, MSI_CloseRecord );
+ if( rec )
+ rec->count = cParams;
+ return rec;
+}
+
+MSIHANDLE WINAPI MsiCreateRecord( unsigned int cParams )
+{
+ MSIRECORD *rec;
+ MSIHANDLE ret = 0;
+
+ TRACE("%d\n", cParams);
+
+ rec = MSI_CreateRecord( cParams );
+ if( rec )
+ ret = alloc_msihandle( &rec->hdr );
+ return ret;
+}
+
+unsigned int MSI_RecordGetFieldCount( MSIRECORD *rec )
+{
+ return rec->count;
+}
+
+unsigned int WINAPI MsiRecordGetFieldCount( MSIHANDLE handle )
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld\n", handle );
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ {
+ ERR("Record not found!\n");
+ return 0;
+ }
+
+ ret = MSI_RecordGetFieldCount( rec );
+ msiobj_release( &rec->hdr );
+
+ return ret;
+}
+
+static BOOL string2intW( LPCWSTR str, int *out )
+{
+ int x = 0;
+ LPCWSTR p = str;
+
+ if( *p == '-' ) /* skip the minus sign */
+ p++;
+ while ( *p )
+ {
+ if( (*p < '0') || (*p > '9') )
+ return FALSE;
+ x *= 10;
+ x += (*p - '0');
+ p++;
+ }
+
+ if( str[0] == '-' ) /* check if it's negative */
+ x = -x;
+ *out = x;
+
+ return TRUE;
+}
+
+int MSI_RecordGetInteger( MSIRECORD *rec, unsigned int iField)
+{
+ int ret = 0;
+
+ TRACE("%p %d\n", rec, iField );
+
+ if( iField > rec->count )
+ return MSI_NULL_INTEGER;
+
+ switch( rec->fields[iField].type )
+ {
+ case MSIFIELD_INT:
+ return rec->fields[iField].u.iVal;
+ case MSIFIELD_WSTR:
+ if( string2intW( rec->fields[iField].u.szwVal, &ret ) )
+ return ret;
+ return MSI_NULL_INTEGER;
+ default:
+ break;
+ }
+
+ return MSI_NULL_INTEGER;
+}
+
+int WINAPI MsiRecordGetInteger( MSIHANDLE handle, unsigned int iField)
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d\n", handle, iField );
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return MSI_NULL_INTEGER;
+
+ ret = MSI_RecordGetInteger( rec, iField );
+ msiobj_release( &rec->hdr );
+
+ return ret;
+}
+
+UINT WINAPI MsiRecordClearData( MSIHANDLE handle )
+{
+ MSIRECORD *rec;
+ UINT i;
+
+ TRACE("%ld\n", handle );
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+
+ for( i=0; i<=rec->count; i++)
+ {
+ MSI_FreeField( &rec->fields[i] );
+ rec->fields[i].type = MSIFIELD_NULL;
+ rec->fields[i].u.iVal = 0;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+UINT MSI_RecordSetInteger( MSIRECORD *rec, unsigned int iField, int iVal )
+{
+ TRACE("%p %u %d\n", rec, iField, iVal);
+
+ if( iField <= rec->count )
+ {
+ MSI_FreeField( &rec->fields[iField] );
+ rec->fields[iField].type = MSIFIELD_INT;
+ rec->fields[iField].u.iVal = iVal;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiRecordSetInteger( MSIHANDLE handle, unsigned int iField, int iVal )
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %u %d\n", handle, iField, iVal);
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+
+ ret = MSI_RecordSetInteger( rec, iField, iVal );
+ msiobj_release( &rec->hdr );
+ return ret;
+}
+
+BOOL MSI_RecordIsNull( MSIRECORD *rec, unsigned int iField )
+{
+ BOOL r = TRUE;
+
+ TRACE("%p %d\n", rec, iField );
+
+ r = ( iField > rec->count ) ||
+ ( rec->fields[iField].type == MSIFIELD_NULL );
+
+ return r;
+}
+
+BOOL WINAPI MsiRecordIsNull( MSIHANDLE handle, unsigned int iField )
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d\n", handle, iField );
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_RecordIsNull( rec, iField );
+ msiobj_release( &rec->hdr );
+ return ret;
+
+}
+
+UINT MSI_RecordGetStringA(MSIRECORD *rec, unsigned int iField,
+ LPSTR szValue, DWORD *pcchValue)
+{
+ UINT len=0, ret;
+ CHAR buffer[16];
+
+ TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
+
+ if( iField > rec->count )
+ return ERROR_INVALID_PARAMETER;
+
+ ret = ERROR_SUCCESS;
+ switch( rec->fields[iField].type )
+ {
+ case MSIFIELD_INT:
+ wsprintfA(buffer, "%d", rec->fields[iField].u.iVal);
+ len = lstrlenA( buffer );
+ lstrcpynA(szValue, buffer, *pcchValue);
+ break;
+ case MSIFIELD_WSTR:
+ len = WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
+ NULL, 0 , NULL, NULL);
+ WideCharToMultiByte( CP_ACP, 0, rec->fields[iField].u.szwVal, -1,
+ szValue, *pcchValue, NULL, NULL);
+ break;
+ case MSIFIELD_NULL:
+ len = 1;
+ if( *pcchValue > 0 )
+ szValue[0] = 0;
+ break;
+ default:
+ ret = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if( *pcchValue < len )
+ ret = ERROR_MORE_DATA;
+ *pcchValue = len;
+
+ return ret;
+}
+
+UINT WINAPI MsiRecordGetStringA(MSIHANDLE handle, unsigned int iField,
+ LPSTR szValue, DWORD *pcchValue)
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d %p %p\n", handle, iField, szValue, pcchValue);
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_RecordGetStringA( rec, iField, szValue, pcchValue);
+ msiobj_release( &rec->hdr );
+ return ret;
+}
+
+const WCHAR *MSI_RecordGetString( MSIRECORD *rec, unsigned int iField )
+{
+ if( iField > rec->count )
+ return NULL;
+
+ if( rec->fields[iField].type != MSIFIELD_WSTR )
+ return NULL;
+
+ return rec->fields[iField].u.szwVal;
+}
+
+UINT MSI_RecordGetStringW(MSIRECORD *rec, unsigned int iField,
+ LPWSTR szValue, DWORD *pcchValue)
+{
+ UINT len=0, ret;
+ WCHAR buffer[16];
+ static const WCHAR szFormat[] = { '%','d',0 };
+
+ TRACE("%p %d %p %p\n", rec, iField, szValue, pcchValue);
+
+ if( iField > rec->count )
+ return ERROR_INVALID_PARAMETER;
+
+ ret = ERROR_SUCCESS;
+ switch( rec->fields[iField].type )
+ {
+ case MSIFIELD_INT:
+ wsprintfW(buffer, szFormat, rec->fields[iField].u.iVal);
+ len = lstrlenW( buffer );
+ lstrcpynW(szValue, buffer, *pcchValue);
+ break;
+ case MSIFIELD_WSTR:
+ len = lstrlenW( rec->fields[iField].u.szwVal );
+ lstrcpynW(szValue, rec->fields[iField].u.szwVal, *pcchValue);
+ break;
+ case MSIFIELD_NULL:
+ len = 1;
+ if( *pcchValue > 0 )
+ szValue[0] = 0;
+ default:
+ break;
+ }
+
+ if( *pcchValue < len )
+ ret = ERROR_MORE_DATA;
+ *pcchValue = len;
+
+ return ret;
+}
+
+UINT WINAPI MsiRecordGetStringW(MSIHANDLE handle, unsigned int iField,
+ LPWSTR szValue, DWORD *pcchValue)
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d %p %p\n", handle, iField, szValue, pcchValue);
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+
+ ret = MSI_RecordGetStringW( rec, iField, szValue, pcchValue );
+ msiobj_release( &rec->hdr );
+ return ret;
+}
+
+UINT WINAPI MsiRecordDataSize(MSIHANDLE hRecord, unsigned int iField)
+{
+ FIXME("%ld %d\n", hRecord, iField);
+ return 0;
+}
+
+UINT MSI_RecordSetStringA( MSIRECORD *rec, unsigned int iField, LPCSTR szValue )
+{
+ LPWSTR str;
+ UINT len;
+
+ TRACE("%p %d %s\n", rec, iField, debugstr_a(szValue));
+
+ if( iField > rec->count )
+ return ERROR_INVALID_FIELD;
+
+ len = MultiByteToWideChar( CP_ACP, 0, szValue, -1, NULL, 0 );
+ str = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, szValue, -1, str, len );
+ MSI_FreeField( &rec->fields[iField] );
+ rec->fields[iField].type = MSIFIELD_WSTR;
+ rec->fields[iField].u.szwVal = str;
+
+ return 0;
+}
+
+UINT WINAPI MsiRecordSetStringA( MSIHANDLE handle, unsigned int iField, LPCSTR szValue )
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d %s\n", handle, iField, debugstr_a(szValue));
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_RecordSetStringA( rec, iField, szValue );
+ msiobj_release( &rec->hdr );
+ return ret;
+}
+
+UINT MSI_RecordSetStringW( MSIRECORD *rec, unsigned int iField, LPCWSTR szValue )
+{
+ LPWSTR str;
+ UINT len;
+
+ TRACE("%p %d %s\n", rec, iField, debugstr_w(szValue));
+
+ if( iField > rec->count )
+ return ERROR_INVALID_FIELD;
+
+ len = lstrlenW(szValue) + 1;
+ str = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR));
+ lstrcpyW( str, szValue );
+
+ MSI_FreeField( &rec->fields[iField] );
+ rec->fields[iField].type = MSIFIELD_WSTR;
+ rec->fields[iField].u.szwVal = str;
+
+ return 0;
+}
+
+UINT WINAPI MsiRecordSetStringW( MSIHANDLE handle, unsigned int iField, LPCWSTR szValue )
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d %s\n", handle, iField, debugstr_w(szValue));
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+
+ ret = MSI_RecordSetStringW( rec, iField, szValue );
+ msiobj_release( &rec->hdr );
+ return ret;
+}
+
+UINT WINAPI MsiFormatRecordA(MSIHANDLE hInstall, MSIHANDLE hRecord, LPSTR szResult, DWORD *sz)
+{
+ FIXME("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, LPWSTR szResult, DWORD *sz)
+{
+ FIXME("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiRecordSetStreamA(MSIHANDLE hRecord, unsigned int iField, LPCSTR szFilename)
+{
+ FIXME("%ld %d %s\n", hRecord, iField, debugstr_a(szFilename));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiRecordSetStreamW(MSIHANDLE hRecord, unsigned int iField, LPCWSTR szFilename)
+{
+ FIXME("%ld %d %s\n", hRecord, iField, debugstr_w(szFilename));
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT MSI_RecordReadStream(MSIRECORD *rec, unsigned int iField, char *buf, DWORD *sz)
+{
+ ULONG count;
+ HRESULT r;
+ IStream *stm;
+
+ TRACE("%p %d %p %p\n", rec, iField, buf, sz);
+
+ if( iField > rec->count )
+ return ERROR_INVALID_FIELD;
+
+ if( rec->fields[iField].type != MSIFIELD_STREAM )
+ {
+ *sz = 0;
+ return ERROR_INVALID_FIELD;
+ }
+
+ stm = rec->fields[iField].u.stream;
+ if( !stm )
+ return ERROR_INVALID_FIELD;
+
+ /* if there's no buffer pointer, calculate the length to the end */
+ if( !buf )
+ {
+ LARGE_INTEGER ofs;
+ ULARGE_INTEGER end, cur;
+
+ ofs.QuadPart = cur.QuadPart = 0;
+ end.QuadPart = 0;
+ r = IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
+ IStream_Seek( stm, ofs, STREAM_SEEK_END, &end );
+ ofs.QuadPart = cur.QuadPart;
+ IStream_Seek( stm, ofs, STREAM_SEEK_SET, &cur );
+ *sz = end.QuadPart - cur.QuadPart;
+
+ return ERROR_SUCCESS;
+ }
+
+ /* read the data */
+ count = 0;
+ r = IStream_Read( stm, buf, *sz, &count );
+ if( FAILED( r ) )
+ return ERROR_FUNCTION_FAILED;
+
+ *sz = count;
+
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiRecordReadStream(MSIHANDLE handle, unsigned int iField, char *buf, DWORD *sz)
+{
+ MSIRECORD *rec;
+ UINT ret;
+
+ TRACE("%ld %d %p %p\n", handle, iField, buf, sz);
+
+ rec = msihandle2msiinfo( handle, MSIHANDLETYPE_RECORD );
+ if( !rec )
+ return ERROR_INVALID_HANDLE;
+ ret = MSI_RecordReadStream( rec, iField, buf, sz );
+ msiobj_release( &rec->hdr );
+ return ret;
+}
+
+UINT MSI_RecordSetIStream( MSIRECORD *rec, unsigned int iField, IStream *stm )
+{
+ TRACE("%p %d %p\n", rec, iField, stm);
+
+ if( iField > rec->count )
+ return ERROR_INVALID_FIELD;
+
+ MSI_FreeField( &rec->fields[iField] );
+
+ rec->fields[iField].type = MSIFIELD_STREAM;
+ rec->fields[iField].u.stream = stm;
+ IStream_AddRef( stm );
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N regsvr.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regsvr.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,624 @@
+/*
+ * self-registerable dll functions for msi.dll
+ *
+ * Copyright (C) 2004 Raphael Junqueira
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "ole2.h"
+#include "olectl.h"
+
+#include "wine/debug.h"
+
+#include "msi.h"
+#include "initguid.h"
+#include "msipriv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+ * Near the bottom of this file are the exported DllRegisterServer and
+ * DllUnregisterServer, which make all this worthwhile.
+ */
+
+/***********************************************************************
+ * interface for self-registering
+ */
+struct regsvr_interface {
+ IID const *iid; /* NULL for end of list */
+ LPCSTR name; /* can be NULL to omit */
+ IID const *base_iid; /* can be NULL to omit */
+ int num_methods; /* can be <0 to omit */
+ CLSID const *ps_clsid; /* can be NULL to omit */
+ CLSID const *ps_clsid32; /* can be NULL to omit */
+};
+
+static HRESULT register_interfaces(struct regsvr_interface const *list);
+static HRESULT unregister_interfaces(struct regsvr_interface const *list);
+
+/**
+ * @todo: maybe adding typelibs support here
+ * [Software\\Classes\\CLSID\\{000C1090-0000-0000-C000-000000000046}\\TypeLib] 1080380217
+ * @="{000C1092-0000-0000-C000-000000000046}"
+ */
+struct regsvr_coclass {
+ CLSID const *clsid; /* NULL for end of list */
+ LPCSTR name; /* can be NULL to omit */
+ LPCSTR iph32; /* can be NULL to omit */
+ LPCSTR ips; /* can be NULL to omit */
+ LPCSTR ips32; /* can be NULL to omit */
+ LPCSTR ips32_tmodel; /* can be NULL to omit, if apartment, iph32 must be set */
+ LPCSTR progid; /* can be NULL to omit */
+ LPCSTR viprogid; /* can be NULL to omit */
+ LPCSTR progid_extra; /* can be NULL to omit */
+};
+
+static HRESULT register_coclasses(struct regsvr_coclass const *list);
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
+
+/***********************************************************************
+ * static string constants
+ */
+static WCHAR const interface_keyname[10] = {
+ 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
+static WCHAR const base_ifa_keyname[14] = {
+ 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
+ 'e', 0 };
+static WCHAR const num_methods_keyname[11] = {
+ 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
+static WCHAR const ps_clsid_keyname[15] = {
+ 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+ 'i', 'd', 0 };
+static WCHAR const ps_clsid32_keyname[17] = {
+ 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+ 'i', 'd', '3', '2', 0 };
+static WCHAR const clsid_keyname[6] = {
+ 'C', 'L', 'S', 'I', 'D', 0 };
+static WCHAR const curver_keyname[7] = {
+ 'C', 'u', 'r', 'V', 'e', 'r', 0 };
+static WCHAR const iph32_keyname[] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'H', 'a', 'n', 'd', 'l', 'e', 'r',
+ '3', '2', 0 };
+static WCHAR const ips_keyname[13] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ 0 };
+static WCHAR const ips32_keyname[15] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ '3', '2', 0 };
+static WCHAR const progid_keyname[7] = {
+ 'P', 'r', 'o', 'g', 'I', 'D', 0 };
+static WCHAR const viprogid_keyname[25] = {
+ 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
+ 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
+ 0 };
+static char const tmodel_valuename[] = "ThreadingModel";
+
+/***********************************************************************
+ * static helper functions
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
+static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
+ WCHAR const *value);
+static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
+ char const *value);
+static LONG register_progid(WCHAR const *clsid,
+ char const *progid, char const *curver_progid,
+ char const *name, char const *extra);
+static LONG recursive_delete_key(HKEY key);
+static LONG recursive_delete_keyA(HKEY base, char const *name);
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
+
+/***********************************************************************
+ * register_interfaces
+ */
+static HRESULT register_interfaces(struct regsvr_interface const *list) {
+ LONG res = ERROR_SUCCESS;
+ HKEY interface_key;
+
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->iid; ++list) {
+ WCHAR buf[39];
+ HKEY iid_key;
+
+ StringFromGUID2(list->iid, buf, 39);
+ res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_interface_key;
+
+ if (list->name) {
+ res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)(list->name),
+ strlen(list->name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->base_iid) {
+ register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (0 <= list->num_methods) {
+ static WCHAR const fmt[3] = { '%', 'd', 0 };
+ HKEY key;
+
+ res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+
+ wsprintfW(buf, fmt, list->num_methods);
+ res = RegSetValueExW(key, NULL, 0, REG_SZ,
+ (CONST BYTE*)buf,
+ (lstrlenW(buf) + 1) * sizeof(WCHAR));
+ RegCloseKey(key);
+
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->ps_clsid) {
+ register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->ps_clsid32) {
+ register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ error_close_iid_key:
+ RegCloseKey(iid_key);
+ }
+
+error_close_interface_key:
+ RegCloseKey(interface_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * unregister_interfaces
+ */
+static HRESULT unregister_interfaces(struct regsvr_interface const *list) {
+ LONG res = ERROR_SUCCESS;
+ HKEY interface_key;
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
+ KEY_READ | KEY_WRITE, &interface_key);
+ if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->iid; ++list) {
+ WCHAR buf[39];
+
+ StringFromGUID2(list->iid, buf, 39);
+ res = recursive_delete_keyW(interface_key, buf);
+ }
+
+ RegCloseKey(interface_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * register_coclasses
+ */
+static HRESULT register_coclasses(struct regsvr_coclass const *list) {
+ LONG res = ERROR_SUCCESS;
+ HKEY coclass_key;
+
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+ WCHAR buf[39];
+ HKEY clsid_key;
+
+ StringFromGUID2(list->clsid, buf, 39);
+ res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+ if (list->name) {
+ res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)(list->name),
+ strlen(list->name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->iph32) {
+ HKEY iph32_key;
+
+ res = RegCreateKeyExW(clsid_key, iph32_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL,
+ &iph32_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = RegSetValueExA(iph32_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)list->iph32,
+ lstrlenA(list->iph32) + 1);
+ RegCloseKey(iph32_key);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->ips) {
+ res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->ips32) {
+ HKEY ips32_key;
+
+ res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL,
+ &ips32_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)list->ips32,
+ lstrlenA(list->ips32) + 1);
+ if (res == ERROR_SUCCESS && list->ips32_tmodel)
+ res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
+ (CONST BYTE*)list->ips32_tmodel,
+ strlen(list->ips32_tmodel) + 1);
+ RegCloseKey(ips32_key);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->progid) {
+ res = register_key_defvalueA(clsid_key, progid_keyname,
+ list->progid);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = register_progid(buf, list->progid, NULL,
+ list->name, list->progid_extra);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->viprogid) {
+ res = register_key_defvalueA(clsid_key, viprogid_keyname,
+ list->viprogid);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = register_progid(buf, list->viprogid, list->progid,
+ list->name, list->progid_extra);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ error_close_clsid_key:
+ RegCloseKey(clsid_key);
+ }
+
+error_close_coclass_key:
+ RegCloseKey(coclass_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * unregister_coclasses
+ */
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list) {
+ LONG res = ERROR_SUCCESS;
+ HKEY coclass_key;
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
+ KEY_READ | KEY_WRITE, &coclass_key);
+ if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+ WCHAR buf[39];
+
+ StringFromGUID2(list->clsid, buf, 39);
+ res = recursive_delete_keyW(coclass_key, buf);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+ if (list->progid) {
+ res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+ }
+
+ if (list->viprogid) {
+ res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+ }
+ }
+
+error_close_coclass_key:
+ RegCloseKey(coclass_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * regsvr_key_guid
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid) {
+ WCHAR buf[39];
+
+ StringFromGUID2(guid, buf, 39);
+ return register_key_defvalueW(base, name, buf);
+}
+
+/***********************************************************************
+ * regsvr_key_defvalueW
+ */
+static LONG register_key_defvalueW(
+ HKEY base,
+ WCHAR const *name,
+ WCHAR const *value) {
+ LONG res;
+ HKEY key;
+
+ res = RegCreateKeyExW(base, name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+ res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+ (lstrlenW(value) + 1) * sizeof(WCHAR));
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * regsvr_key_defvalueA
+ */
+static LONG register_key_defvalueA(
+ HKEY base,
+ WCHAR const *name,
+ char const *value) {
+ LONG res;
+ HKEY key;
+
+ res = RegCreateKeyExW(base, name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+ res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+ lstrlenA(value) + 1);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * regsvr_progid
+ */
+static LONG register_progid(
+ WCHAR const *clsid,
+ char const *progid,
+ char const *curver_progid,
+ char const *name,
+ char const *extra) {
+ LONG res;
+ HKEY progid_key;
+
+ res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
+ NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &progid_key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+
+ if (name) {
+ res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)name, strlen(name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (clsid) {
+ res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (curver_progid) {
+ res = register_key_defvalueA(progid_key, curver_keyname,
+ curver_progid);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (extra) {
+ HKEY extra_key;
+
+ res = RegCreateKeyExA(progid_key, extra, 0,
+ NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &extra_key, NULL);
+ if (res == ERROR_SUCCESS)
+ RegCloseKey(extra_key);
+ }
+
+error_close_progid_key:
+ RegCloseKey(progid_key);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_key
+ */
+static LONG recursive_delete_key(HKEY key) {
+ LONG res;
+ WCHAR subkey_name[MAX_PATH];
+ DWORD cName;
+ HKEY subkey;
+
+ for (;;) {
+ cName = sizeof(subkey_name) / sizeof(WCHAR);
+ res = RegEnumKeyExW(key, 0, subkey_name, &cName,
+ NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
+ res = ERROR_SUCCESS; /* presumably we're done enumerating */
+ break;
+ }
+ res = RegOpenKeyExW(key, subkey_name, 0,
+ KEY_READ | KEY_WRITE, &subkey);
+ if (res == ERROR_FILE_NOT_FOUND) continue;
+ if (res != ERROR_SUCCESS) break;
+
+ res = recursive_delete_key(subkey);
+ RegCloseKey(subkey);
+ if (res != ERROR_SUCCESS) break;
+ }
+
+ if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_keyA
+ */
+static LONG recursive_delete_keyA(HKEY base, char const *name) {
+ LONG res;
+ HKEY key;
+
+ res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
+ if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+ if (res != ERROR_SUCCESS) return res;
+ res = recursive_delete_key(key);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_keyW
+ */
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name) {
+ LONG res;
+ HKEY key;
+
+ res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
+ if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+ if (res != ERROR_SUCCESS) return res;
+ res = recursive_delete_key(key);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * coclass list
+ */
+static struct regsvr_coclass const coclass_list[] = {
+ {
+ &CLSID_IMsiServer,
+ "Msi install server",
+ "ole32.dll",
+ NULL,
+ "msi.dll",
+ "Apartment",
+ "WindowsInstaller.Installer",
+ NULL
+ },
+ {
+ &CLSID_IMsiServerMessage,
+ "Wine Installer Message RPC",
+ NULL,
+ NULL,
+ "msi.dll",
+ NULL,
+ "WindowsInstaller.Message",
+ NULL
+ },
+ {
+ &CLSID_IMsiServerX1,
+ "Msi install server",
+ "ole32.dll",
+ NULL,
+ "msi.dll",
+ "Apartment",
+ "WindowsInstaller.Installer",
+ NULL
+ },
+ {
+ &CLSID_IMsiServerX2,
+ "Msi install server",
+ "ole32.dll",
+ NULL,
+ "msi.dll",
+ "Apartment",
+ "WindowsInstaller.Installer",
+ NULL
+ },
+ {
+ &CLSID_IMsiServerX3,
+ "Msi install server",
+ "ole32.dll",
+ NULL,
+ "msi.dll",
+ "Apartment",
+ "WindowsInstaller.Installer",
+ NULL
+ },
+ { NULL } /* list terminator */
+};
+
+/***********************************************************************
+ * interface list
+ */
+/*
+ * we should declare: (@see ole32/regsvr.c for examples)
+ [-HKEY_CLASSES_ROOT\Interface\{000C101C-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C101D-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C1025-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C1033-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C1090-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C1093-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C1095-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C109A-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C109B-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C109C-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C109D-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C109E-0000-0000-C000-000000000046}]
+ [-HKEY_CLASSES_ROOT\Interface\{000C109F-0000-0000-C000-000000000046}]
+*/
+static struct regsvr_interface const interface_list[] = {
+ { NULL } /* list terminator */
+};
+
+/***********************************************************************
+ * DllRegisterServer
+ */
+HRESULT WINAPI MSI_DllRegisterServer(void) {
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = register_coclasses(coclass_list);
+ if (SUCCEEDED(hr))
+ hr = register_interfaces(interface_list);
+ return hr;
+}
+
+/***********************************************************************
+ * DllUnregisterServer
+ */
+HRESULT WINAPI MSI_DllUnregisterServer(void) {
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = unregister_coclasses(coclass_list);
+ if (SUCCEEDED(hr))
+ hr = unregister_interfaces(interface_list);
+ return hr;
+}
reactos/lib/msi
diff -N select.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ select.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,290 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSISELECTVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ MSIVIEW *table;
+ UINT num_cols;
+ UINT max_cols;
+ UINT cols[1];
+} MSISELECTVIEW;
+
+static UINT SELECT_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %d %d %p\n", sv, row, col, val );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( (col==0) || (col>sv->num_cols) )
+ return ERROR_FUNCTION_FAILED;
+
+ col = sv->cols[ col - 1 ];
+
+ return sv->table->ops->fetch_int( sv->table, row, col, val );
+}
+
+static UINT SELECT_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %d %d %p\n", sv, row, col, stm );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( (col==0) || (col>sv->num_cols) )
+ return ERROR_FUNCTION_FAILED;
+
+ col = sv->cols[ col - 1 ];
+
+ return sv->table->ops->fetch_stream( sv->table, row, col, stm );
+}
+
+static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %d %d %04x\n", sv, row, col, val );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( (col==0) || (col>sv->num_cols) )
+ return ERROR_FUNCTION_FAILED;
+
+ col = sv->cols[ col - 1 ];
+
+ return sv->table->ops->set_int( sv->table, row, col, val );
+}
+
+static UINT SELECT_insert_row( struct tagMSIVIEW *view, UINT *num )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %p\n", sv, num );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->table->ops->insert_row( sv->table, num );
+}
+
+static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %p\n", sv, record);
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->table->ops->execute( sv->table, record );
+}
+
+static UINT SELECT_close( struct tagMSIVIEW *view )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p\n", sv );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->table->ops->close( sv->table );
+}
+
+static UINT SELECT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %p %p\n", sv, rows, cols );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( cols )
+ *cols = sv->num_cols;
+
+ return sv->table->ops->get_dimensions( sv->table, rows, NULL );
+}
+
+static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %d %p %p\n", sv, n, name, type );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( (n==0) || (n>sv->num_cols) )
+ return ERROR_FUNCTION_FAILED;
+
+ n = sv->cols[ n - 1 ];
+
+ return sv->table->ops->get_column_info( sv->table, n, name, type );
+}
+
+static UINT SELECT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p %d %ld\n", sv, eModifyMode, hrec );
+
+ if( !sv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return sv->table->ops->modify( sv->table, eModifyMode, hrec );
+}
+
+static UINT SELECT_delete( struct tagMSIVIEW *view )
+{
+ MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+
+ TRACE("%p\n", sv );
+
+ if( sv->table )
+ sv->table->ops->delete( sv->table );
+
+ HeapFree( GetProcessHeap(), 0, sv );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS select_ops =
+{
+ SELECT_fetch_int,
+ SELECT_fetch_stream,
+ SELECT_set_int,
+ SELECT_insert_row,
+ SELECT_execute,
+ SELECT_close,
+ SELECT_get_dimensions,
+ SELECT_get_column_info,
+ SELECT_modify,
+ SELECT_delete
+};
+
+static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPWSTR name )
+{
+ UINT r, n=0;
+ MSIVIEW *table;
+
+ TRACE("%p adding %s\n", sv, debugstr_w( name ) );
+
+ if( sv->view.ops != &select_ops )
+ return ERROR_FUNCTION_FAILED;
+
+ table = sv->table;
+ if( !table )
+ return ERROR_FUNCTION_FAILED;
+ if( !table->ops->get_dimensions )
+ return ERROR_FUNCTION_FAILED;
+ if( !table->ops->get_column_info )
+ return ERROR_FUNCTION_FAILED;
+
+ if( sv->num_cols >= sv->max_cols )
+ return ERROR_FUNCTION_FAILED;
+
+ r = VIEW_find_column( table, name, &n );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ sv->cols[sv->num_cols] = n;
+ TRACE("Translating column %s from %d -> %d\n",
+ debugstr_w( name ), sv->num_cols, n);
+
+ sv->num_cols++;
+
+ return ERROR_SUCCESS;
+}
+
+UINT SELECT_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+ string_list *columns )
+{
+ MSISELECTVIEW *sv = NULL;
+ UINT count = 0, r;
+
+ TRACE("%p\n", sv );
+
+ r = table->ops->get_dimensions( table, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("can't get table dimensions\n");
+ return r;
+ }
+
+ sv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof *sv + count*sizeof (UINT) );
+ if( !sv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ sv->view.ops = &select_ops;
+ sv->db = db;
+ sv->table = table;
+ sv->num_cols = 0;
+ sv->max_cols = count;
+
+ while( columns )
+ {
+ r = SELECT_AddColumn( sv, columns->string );
+ if( r )
+ break;
+ columns = columns->next;
+ }
+
+ if( r != ERROR_SUCCESS )
+ {
+ sv->view.ops->delete( &sv->view );
+ sv = NULL;
+ }
+
+ *view = &sv->view;
+
+ return r;
+}
reactos/lib/msi
diff -N sql.tab.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sql.tab.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,2180 @@
+/* A Bison parser, made from ./sql.y
+ by GNU bison 1.35. */
+
+#define YYBISON 1 /* Identify Bison output. */
+
+#define yyparse SQL_parse
+#define yylex SQL_lex
+#define yyerror SQL_error
+#define yylval SQL_lval
+#define yychar SQL_char
+#define yydebug SQL_debug
+#define yynerrs SQL_nerrs
+# define TK_ABORT 257
+# define TK_AFTER 258
+# define TK_AGG_FUNCTION 259
+# define TK_ALL 260
+# define TK_AND 261
+# define TK_AS 262
+# define TK_ASC 263
+# define TK_BEFORE 264
+# define TK_BEGIN 265
+# define TK_BETWEEN 266
+# define TK_BITAND 267
+# define TK_BITNOT 268
+# define TK_BITOR 269
+# define TK_BY 270
+# define TK_CASCADE 271
+# define TK_CASE 272
+# define TK_CHAR 273
+# define TK_CHECK 274
+# define TK_CLUSTER 275
+# define TK_COLLATE 276
+# define TK_COLUMN 277
+# define TK_COMMA 278
+# define TK_COMMENT 279
+# define TK_COMMIT 280
+# define TK_CONCAT 281
+# define TK_CONFLICT 282
+# define TK_CONSTRAINT 283
+# define TK_COPY 284
+# define TK_CREATE 285
+# define TK_DEFAULT 286
+# define TK_DEFERRABLE 287
+# define TK_DEFERRED 288
+# define TK_DELETE 289
+# define TK_DELIMITERS 290
+# define TK_DESC 291
+# define TK_DISTINCT 292
+# define TK_DOT 293
+# define TK_DROP 294
+# define TK_EACH 295
+# define TK_ELSE 296
+# define TK_END 297
+# define TK_END_OF_FILE 298
+# define TK_EQ 299
+# define TK_EXCEPT 300
+# define TK_EXPLAIN 301
+# define TK_FAIL 302
+# define TK_FLOAT 303
+# define TK_FOR 304
+# define TK_FOREIGN 305
+# define TK_FROM 306
+# define TK_FUNCTION 307
+# define TK_GE 308
+# define TK_GLOB 309
+# define TK_GROUP 310
+# define TK_GT 311
+# define TK_HAVING 312
+# define TK_HOLD 313
+# define TK_IGNORE 314
+# define TK_ILLEGAL 315
+# define TK_IMMEDIATE 316
+# define TK_IN 317
+# define TK_INDEX 318
+# define TK_INITIALLY 319
+# define TK_ID 320
+# define TK_INSERT 321
+# define TK_INSTEAD 322
+# define TK_INT 323
+# define TK_INTEGER 324
+# define TK_INTERSECT 325
+# define TK_INTO 326
+# define TK_IS 327
+# define TK_ISNULL 328
+# define TK_JOIN 329
+# define TK_JOIN_KW 330
+# define TK_KEY 331
+# define TK_LE 332
+# define TK_LIKE 333
+# define TK_LIMIT 334
+# define TK_LONG 335
+# define TK_LONGCHAR 336
+# define TK_LP 337
+# define TK_LSHIFT 338
+# define TK_LT 339
+# define TK_LOCALIZABLE 340
+# define TK_MATCH 341
+# define TK_MINUS 342
+# define TK_NE 343
+# define TK_NOT 344
+# define TK_NOTNULL 345
+# define TK_NULL 346
+# define TK_OBJECT 347
+# define TK_OF 348
+# define TK_OFFSET 349
+# define TK_ON 350
+# define TK_OR 351
+# define TK_ORACLE_OUTER_JOIN 352
+# define TK_ORDER 353
+# define TK_PLUS 354
+# define TK_PRAGMA 355
+# define TK_PRIMARY 356
+# define TK_RAISE 357
+# define TK_REFERENCES 358
+# define TK_REM 359
+# define TK_REPLACE 360
+# define TK_RESTRICT 361
+# define TK_ROLLBACK 362
+# define TK_ROW 363
+# define TK_RP 364
+# define TK_RSHIFT 365
+# define TK_SELECT 366
+# define TK_SEMI 367
+# define TK_SET 368
+# define TK_SHORT 369
+# define TK_SLASH 370
+# define TK_SPACE 371
+# define TK_STAR 372
+# define TK_STATEMENT 373
+# define TK_STRING 374
+# define TK_TABLE 375
+# define TK_TEMP 376
+# define TK_THEN 377
+# define TK_TRANSACTION 378
+# define TK_TRIGGER 379
+# define TK_UMINUS 380
+# define TK_UNCLOSED_STRING 381
+# define TK_UNION 382
+# define TK_UNIQUE 383
+# define TK_UPDATE 384
+# define TK_UPLUS 385
+# define TK_USING 386
+# define TK_VACUUM 387
+# define TK_VALUES 388
+# define TK_VIEW 389
+# define TK_WHEN 390
+# define TK_WHERE 391
+# define TK_WILDCARD 392
+# define END_OF_FILE 393
+# define ILLEGAL 394
+# define SPACE 395
+# define UNCLOSED_STRING 396
+# define COMMENT 397
+# define FUNCTION 398
+# define COLUMN 399
+
+#line 1 "./sql.y"
+
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "query.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+extern int SQL_error(const char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_SQL_input
+{
+ MSIDATABASE *db;
+ LPCWSTR command;
+ DWORD n, len;
+ MSIVIEW **view; /* view structure for the resulting query */
+} SQL_input;
+
+static LPWSTR SQL_getstring( struct sql_str *str );
+static INT SQL_getint( SQL_input *sql );
+static int SQL_lex( void *SQL_lval, SQL_input *info);
+
+static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in,
+ string_list *columns );
+static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in,
+ string_list *columns );
+
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
+ string_list *keys);
+
+static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_column( LPWSTR );
+static struct expr * EXPR_ival( struct sql_str *);
+static struct expr * EXPR_sval( struct sql_str *);
+static struct expr * EXPR_wildcard();
+
+
+#line 73 "./sql.y"
+#ifndef YYSTYPE
+typedef union
+{
+ struct sql_str str;
+ LPWSTR string;
+ string_list *column_list;
+ value_list *val_list;
+ MSIVIEW *query;
+ struct expr *expr;
+ USHORT column_type;
+ create_col_info *column_info;
+ column_assignment update_col_info;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+
+
+#define YYFINAL 121
+#define YYFLAG -32768
+#define YYNTBASE 147
+
+/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
+#define YYTRANSLATE(x) ((unsigned)(x) <= 400 ? yytranslate[x] : 171)
+
+/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
+static const short yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
+ 126, 127, 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
+ 146
+};
+
+#if YYDEBUG
+static const short yyprhs[] =
+{
+ 0, 0, 2, 4, 6, 8, 19, 31, 38, 46,
+ 53, 58, 63, 66, 68, 71, 73, 77, 79, 84,
+ 86, 88, 90, 92, 94, 96, 101, 103, 107, 112,
+ 114, 118, 120, 123, 128, 132, 136, 140, 144, 148,
+ 152, 156, 160, 164, 168, 172, 177, 179, 181, 183,
+ 187, 189, 193, 197, 199, 201, 203, 205, 209, 211,
+ 213, 215
+};
+static const short yyrhs[] =
+{
+ 157, 0, 149, 0, 148, 0, 150, 0, 67, 72,
+ 169, 83, 159, 110, 134, 83, 163, 110, 0, 67,
+ 72, 169, 83, 159, 110, 134, 83, 163, 110, 122,
+ 0, 31, 121, 169, 83, 151, 110, 0, 31, 121,
+ 169, 83, 151, 110, 59, 0, 130, 169, 114, 164,
+ 137, 161, 0, 152, 102, 77, 159, 0, 152, 24,
+ 168, 153, 0, 168, 153, 0, 154, 0, 154, 86,
+ 0, 155, 0, 155, 90, 92, 0, 19, 0, 19,
+ 83, 156, 110, 0, 82, 0, 115, 0, 69, 0,
+ 81, 0, 93, 0, 70, 0, 158, 99, 16, 159,
+ 0, 158, 0, 112, 159, 160, 0, 112, 38, 159,
+ 160, 0, 168, 0, 168, 24, 159, 0, 118, 0,
+ 52, 169, 0, 52, 169, 137, 161, 0, 83, 161,
+ 110, 0, 167, 45, 167, 0, 161, 7, 161, 0,
+ 161, 97, 161, 0, 167, 45, 162, 0, 167, 57,
+ 162, 0, 167, 85, 162, 0, 167, 78, 162, 0,
+ 167, 54, 162, 0, 167, 89, 162, 0, 167, 73,
+ 92, 0, 167, 73, 90, 92, 0, 167, 0, 166,
+ 0, 166, 0, 163, 24, 166, 0, 165, 0, 165,
+ 24, 164, 0, 168, 45, 166, 0, 70, 0, 120,
+ 0, 138, 0, 168, 0, 169, 39, 170, 0, 170,
+ 0, 170, 0, 66, 0, 120, 0
+};
+
+#endif
+
+#if YYDEBUG
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const short yyrline[] =
+{
+ 0, 141, 147, 152, 157, 164, 173, 183, 194, 206,
+ 217, 227, 247, 258, 263, 270, 275, 281, 286, 290,
+ 294, 298, 302, 306, 312, 323, 335, 338, 353, 370,
+ 384, 397, 403, 415, 433, 438, 442, 446, 450, 454,
+ 458, 462, 466, 470, 474, 478, 484, 486, 489, 502,
+ 517, 519, 527, 543, 548, 552, 558, 565, 570, 576,
+ 583, 588
+};
+#endif
+
+
+#if (YYDEBUG) || defined YYERROR_VERBOSE
+
+/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
+static const char *const yytname[] =
+{
+ "$", "error", "$undefined.", "TK_ABORT", "TK_AFTER", "TK_AGG_FUNCTION",
+ "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE", "TK_BEGIN",
+ "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY",
+ "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER",
+ "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT",
+ "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE",
+ "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE",
+ "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP",
+ "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT",
+ "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM",
+ "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING",
+ "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN",
+ "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD",
+ "TK_INT", "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL",
+ "TK_JOIN", "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT",
+ "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT",
+ "TK_LOCALIZABLE", "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT",
+ "TK_NOTNULL", "TK_NULL", "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON",
+ "TK_OR", "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA",
+ "TK_PRIMARY", "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE",
+ "TK_RESTRICT", "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT",
+ "TK_SELECT", "TK_SEMI", "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE",
+ "TK_STAR", "TK_STATEMENT", "TK_STRING", "TK_TABLE", "TK_TEMP",
+ "TK_THEN", "TK_TRANSACTION", "TK_TRIGGER", "TK_UMINUS",
+ "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE", "TK_UPDATE", "TK_UPLUS",
+ "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW", "TK_WHEN", "TK_WHERE",
+ "TK_WILDCARD", "END_OF_FILE", "ILLEGAL", "SPACE", "UNCLOSED_STRING",
+ "COMMENT", "FUNCTION", "COLUMN", "AGG_FUNCTION.", "onequery",
+ "oneinsert", "onecreate", "oneupdate", "table_def", "column_def",
+ "column_type", "data_type_l", "data_type", "data_count", "oneselect",
+ "unorderedsel", "selcollist", "from", "expr", "val", "constlist",
+ "update_assign_list", "column_assignment", "const_val", "column_val",
+ "column", "table", "string_or_id", 0
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const short yyr1[] =
+{
+ 0, 147, 147, 147, 147, 148, 148, 149, 149, 150,
+ 151, 152, 152, 153, 153, 154, 154, 155, 155, 155,
+ 155, 155, 155, 155, 156, 157, 157, 158, 158, 159,
+ 159, 159, 160, 160, 161, 161, 161, 161, 161, 161,
+ 161, 161, 161, 161, 161, 161, 162, 162, 163, 163,
+ 164, 164, 165, 166, 166, 166, 167, 168, 168, 169,
+ 170, 170
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const short yyr2[] =
+{
+ 0, 1, 1, 1, 1, 10, 11, 6, 7, 6,
+ 4, 4, 2, 1, 2, 1, 3, 1, 4, 1,
+ 1, 1, 1, 1, 1, 4, 1, 3, 4, 1,
+ 3, 1, 2, 4, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 4, 1, 1, 1, 3,
+ 1, 3, 3, 1, 1, 1, 1, 3, 1, 1,
+ 1, 1
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+ doesn't specify something else to do. Zero means the default is an
+ error. */
+static const short yydefact[] =
+{
+ 0, 0, 0, 0, 0, 3, 2, 4, 1, 26,
+ 0, 0, 0, 60, 31, 61, 0, 29, 0, 58,
+ 0, 59, 0, 0, 0, 0, 0, 27, 0, 0,
+ 0, 0, 0, 0, 28, 32, 30, 57, 0, 50,
+ 0, 25, 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 0, 0, 17, 21, 22, 19, 23, 20, 12,
+ 13, 15, 0, 0, 33, 0, 56, 9, 51, 53,
+ 54, 55, 52, 8, 0, 0, 0, 14, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 11, 10, 24, 0, 16, 0, 34, 36, 37, 54,
+ 38, 47, 35, 42, 46, 39, 0, 44, 41, 40,
+ 43, 18, 0, 48, 45, 0, 5, 49, 6, 0,
+ 0, 0
+};
+
+static const short yydefgoto[] =
+{
+ 119, 5, 6, 7, 42, 43, 59, 60, 61, 93,
+ 8, 9, 16, 27, 64, 100, 112, 38, 39, 101,
+ 65, 66, 18, 19
+};
+
+static const short yypact[] =
+{
+ -30, -113, -49, -34, -50,-32768,-32768,-32768,-32768, -79,
+ -50, -50, -52,-32768,-32768,-32768, -25, 4, -10, 0,
+ -72,-32768, 30, -36, -35, -25, -50,-32768, -52, -50,
+ -50, -52, -50, -52,-32768, -87,-32768,-32768, -84, 33,
+ 13,-32768, -51, -15, -17, -41, -53, -53, -50, -58,
+ 1, -50, -5, -8,-32768,-32768,-32768,-32768,-32768,-32768,
+ -13, -9, -57, -53, -4, 47,-32768, -4,-32768,-32768,
+ -32768,-32768,-32768,-32768, -17, -52, 18,-32768, -3, 11,
+ -7, -53, -53, -59, -59, -59, -71, -59, -59, -59,
+ -32768,-32768,-32768, -14,-32768, -58,-32768, -4, -4, 56,
+ -32768,-32768,-32768,-32768,-32768,-32768, 5,-32768,-32768,-32768,
+ -32768,-32768, -19,-32768,-32768, -58, -23,-32768,-32768, 102,
+ 108,-32768
+};
+
+static const short yypgoto[] =
+{
+ -32768,-32768,-32768,-32768,-32768,-32768, 40,-32768,-32768,-32768,
+ -32768,-32768, 10, 93, -37, 28,-32768, 71,-32768, -32,
+ 22, 3, 14, 45
+};
+
+
+#define YYLAST 136
+
+
+static const short yytable[] =
+{
+ 81, 1, 53, 81, 12, 115, 17, 13, 10, 51,
+ 67, 69, 69, 13, 13, 17, 13, 72, 20, 106,
+ 22, 107, 25, 11, 23, 24, 80, 26, 28, 29,
+ 63, 17, 13, 40, 17, 44, 17, 2, 36, -59,
+ 35, 41, 30, 45, 97, 98, 31, 32, 33, 21,
+ 46, 40, 54, 47, 74, 21, 21, 48, 49, 50,
+ 73, 99, 70, 113, 55, 56, 14, 15, 15, 62,
+ 15, 21, 75, 77, 37, 76, 57, 79, 17, 71,
+ 71, 78, 3, 117, 14, 91, 15, 52, 92, 94,
+ 82, 116, 83, 82, 95, -61, 111, 114, 58, 118,
+ 4, 84, 120, 96, 85, 102, 104, 104, 121, 104,
+ 104, 104, 103, 105, 90, 108, 109, 110, 34, 68,
+ 86, 0, 0, 0, 0, 87, 0, 0, 0, 0,
+ 0, 0, 88, 0, 0, 0, 89
+};
+
+static const short yycheck[] =
+{
+ 7, 31, 19, 7, 38, 24, 3, 66, 121, 24,
+ 47, 70, 70, 66, 66, 12, 66, 49, 4, 90,
+ 99, 92, 12, 72, 10, 11, 63, 52, 24, 39,
+ 83, 28, 66, 30, 31, 32, 33, 67, 28, 39,
+ 26, 31, 114, 33, 81, 82, 16, 83, 83, 4,
+ 137, 48, 69, 137, 51, 10, 11, 24, 45, 110,
+ 59, 120, 120, 95, 81, 82, 118, 120, 120, 110,
+ 120, 26, 77, 86, 29, 83, 93, 134, 75, 138,
+ 138, 90, 112, 115, 118, 75, 120, 102, 70, 92,
+ 97, 110, 45, 97, 83, 39, 110, 92, 115, 122,
+ 130, 54, 0, 110, 57, 83, 84, 85, 0, 87,
+ 88, 89, 84, 85, 74, 87, 88, 89, 25, 48,
+ 73, -1, -1, -1, -1, 78, -1, -1, -1, -1,
+ -1, -1, 85, -1, -1, -1, 89
+};
+#define YYPURE 1
+
+/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
+#line 3 "/usr/share/bison/bison.simple"
+
+/* Skeleton output parser for bison,
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
+
+ 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, 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. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* This is the parser code that is written into each bison parser when
+ the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE)
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+# if YYLSP_NEEDED
+ YYLTYPE yyls;
+# endif
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# if YYLSP_NEEDED
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAX)
+# else
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAX)
+# endif
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY -2
+#define YYEOF 0
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+#define YYFAIL goto yyerrlab
+#define YYRECOVERING() (!!yyerrstatus)
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yychar1 = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up"); \
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run).
+
+ When YYLLOC_DEFAULT is run, CURRENT is set the location of the
+ first token. By default, to implement support for ranges, extend
+ its range to the last symbol. */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#if YYPURE
+# if YYLSP_NEEDED
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval, &yylloc)
+# endif
+# else /* !YYLSP_NEEDED */
+# ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+# else
+# define YYLEX yylex (&yylval)
+# endif
+# endif /* !YYLSP_NEEDED */
+#else /* !YYPURE */
+# define YYLEX yylex ()
+#endif /* !YYPURE */
+
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+#ifdef YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+#endif
+
+#line 315 "/usr/share/bison/bison.simple"
+
+
+/* The user can define YYPARSE_PARAM as the name of an argument to be passed
+ into yyparse. The argument should have type void *.
+ It should actually point to an object.
+ Grammar actions can access the variable by casting it
+ to the proper pointer type. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL
+# else
+# define YYPARSE_PARAM_ARG YYPARSE_PARAM
+# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+# endif
+#else /* !YYPARSE_PARAM */
+# define YYPARSE_PARAM_ARG
+# define YYPARSE_PARAM_DECL
+#endif /* !YYPARSE_PARAM */
+
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+# ifdef YYPARSE_PARAM
+int yyparse (void *);
+# else
+int yyparse (void);
+# endif
+#endif
+
+/* YY_DECL_VARIABLES -- depending whether we use a pure parser,
+ variables are global, or local to YYPARSE. */
+
+#define YY_DECL_NON_LSP_VARIABLES \
+/* The lookahead symbol. */ \
+int yychar; \
+ \
+/* The semantic value of the lookahead symbol. */ \
+YYSTYPE yylval; \
+ \
+/* Number of parse errors so far. */ \
+int yynerrs;
+
+#if YYLSP_NEEDED
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES \
+ \
+/* Location data for the lookahead symbol. */ \
+YYLTYPE yylloc;
+#else
+# define YY_DECL_VARIABLES \
+YY_DECL_NON_LSP_VARIABLES
+#endif
+
+
+/* If nonreentrant, generate the variables here. */
+
+#if !YYPURE
+YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+int
+yyparse (YYPARSE_PARAM_ARG)
+ YYPARSE_PARAM_DECL
+{
+ /* If reentrant, generate the variables here. */
+#if YYPURE
+ YY_DECL_VARIABLES
+#endif /* !YYPURE */
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yychar1 = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+#if YYLSP_NEEDED
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls = yylsa;
+ YYLTYPE *yylsp;
+#endif
+
+#if YYLSP_NEEDED
+# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#else
+# define YYPOPSTACK (yyvsp--, yyssp--)
+#endif
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+#if YYLSP_NEEDED
+ YYLTYPE yyloc;
+#endif
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+#if YYLSP_NEEDED
+ yylsp = yyls;
+#endif
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
[truncated at 1000 lines; 1184 more skipped]
reactos/lib/msi
diff -N sql.tab.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sql.tab.h 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,165 @@
+#ifndef BISON_SQL_TAB_H
+# define BISON_SQL_TAB_H
+
+#ifndef YYSTYPE
+typedef union
+{
+ struct sql_str str;
+ LPWSTR string;
+ string_list *column_list;
+ value_list *val_list;
+ MSIVIEW *query;
+ struct expr *expr;
+ USHORT column_type;
+ create_col_info *column_info;
+ column_assignment update_col_info;
+} yystype;
+# define YYSTYPE yystype
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define TK_ABORT 257
+# define TK_AFTER 258
+# define TK_AGG_FUNCTION 259
+# define TK_ALL 260
+# define TK_AND 261
+# define TK_AS 262
+# define TK_ASC 263
+# define TK_BEFORE 264
+# define TK_BEGIN 265
+# define TK_BETWEEN 266
+# define TK_BITAND 267
+# define TK_BITNOT 268
+# define TK_BITOR 269
+# define TK_BY 270
+# define TK_CASCADE 271
+# define TK_CASE 272
+# define TK_CHAR 273
+# define TK_CHECK 274
+# define TK_CLUSTER 275
+# define TK_COLLATE 276
+# define TK_COLUMN 277
+# define TK_COMMA 278
+# define TK_COMMENT 279
+# define TK_COMMIT 280
+# define TK_CONCAT 281
+# define TK_CONFLICT 282
+# define TK_CONSTRAINT 283
+# define TK_COPY 284
+# define TK_CREATE 285
+# define TK_DEFAULT 286
+# define TK_DEFERRABLE 287
+# define TK_DEFERRED 288
+# define TK_DELETE 289
+# define TK_DELIMITERS 290
+# define TK_DESC 291
+# define TK_DISTINCT 292
+# define TK_DOT 293
+# define TK_DROP 294
+# define TK_EACH 295
+# define TK_ELSE 296
+# define TK_END 297
+# define TK_END_OF_FILE 298
+# define TK_EQ 299
+# define TK_EXCEPT 300
+# define TK_EXPLAIN 301
+# define TK_FAIL 302
+# define TK_FLOAT 303
+# define TK_FOR 304
+# define TK_FOREIGN 305
+# define TK_FROM 306
+# define TK_FUNCTION 307
+# define TK_GE 308
+# define TK_GLOB 309
+# define TK_GROUP 310
+# define TK_GT 311
+# define TK_HAVING 312
+# define TK_HOLD 313
+# define TK_IGNORE 314
+# define TK_ILLEGAL 315
+# define TK_IMMEDIATE 316
+# define TK_IN 317
+# define TK_INDEX 318
+# define TK_INITIALLY 319
+# define TK_ID 320
+# define TK_INSERT 321
+# define TK_INSTEAD 322
+# define TK_INT 323
+# define TK_INTEGER 324
+# define TK_INTERSECT 325
+# define TK_INTO 326
+# define TK_IS 327
+# define TK_ISNULL 328
+# define TK_JOIN 329
+# define TK_JOIN_KW 330
+# define TK_KEY 331
+# define TK_LE 332
+# define TK_LIKE 333
+# define TK_LIMIT 334
+# define TK_LONG 335
+# define TK_LONGCHAR 336
+# define TK_LP 337
+# define TK_LSHIFT 338
+# define TK_LT 339
+# define TK_LOCALIZABLE 340
+# define TK_MATCH 341
+# define TK_MINUS 342
+# define TK_NE 343
+# define TK_NOT 344
+# define TK_NOTNULL 345
+# define TK_NULL 346
+# define TK_OBJECT 347
+# define TK_OF 348
+# define TK_OFFSET 349
+# define TK_ON 350
+# define TK_OR 351
+# define TK_ORACLE_OUTER_JOIN 352
+# define TK_ORDER 353
+# define TK_PLUS 354
+# define TK_PRAGMA 355
+# define TK_PRIMARY 356
+# define TK_RAISE 357
+# define TK_REFERENCES 358
+# define TK_REM 359
+# define TK_REPLACE 360
+# define TK_RESTRICT 361
+# define TK_ROLLBACK 362
+# define TK_ROW 363
+# define TK_RP 364
+# define TK_RSHIFT 365
+# define TK_SELECT 366
+# define TK_SEMI 367
+# define TK_SET 368
+# define TK_SHORT 369
+# define TK_SLASH 370
+# define TK_SPACE 371
+# define TK_STAR 372
+# define TK_STATEMENT 373
+# define TK_STRING 374
+# define TK_TABLE 375
+# define TK_TEMP 376
+# define TK_THEN 377
+# define TK_TRANSACTION 378
+# define TK_TRIGGER 379
+# define TK_UMINUS 380
+# define TK_UNCLOSED_STRING 381
+# define TK_UNION 382
+# define TK_UNIQUE 383
+# define TK_UPDATE 384
+# define TK_UPLUS 385
+# define TK_USING 386
+# define TK_VACUUM 387
+# define TK_VALUES 388
+# define TK_VIEW 389
+# define TK_WHEN 390
+# define TK_WHERE 391
+# define TK_WILDCARD 392
+# define END_OF_FILE 393
+# define ILLEGAL 394
+# define SPACE 395
+# define UNCLOSED_STRING 396
+# define COMMENT 397
+# define FUNCTION 398
+# define COLUMN 399
+
+
+#endif /* not BISON_SQL_TAB_H */
reactos/lib/msi
diff -N sql.y
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sql.y 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,828 @@
+%{
+
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "query.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#define YYLEX_PARAM info
+#define YYPARSE_PARAM info
+
+extern int SQL_error(const char *str);
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tag_SQL_input
+{
+ MSIDATABASE *db;
+ LPCWSTR command;
+ DWORD n, len;
+ MSIVIEW **view; /* view structure for the resulting query */
+} SQL_input;
+
+static LPWSTR SQL_getstring( struct sql_str *str );
+static INT SQL_getint( SQL_input *sql );
+static int SQL_lex( void *SQL_lval, SQL_input *info);
+
+static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in,
+ string_list *columns );
+static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in,
+ string_list *columns );
+
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
+ string_list *keys);
+
+static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_column( LPWSTR );
+static struct expr * EXPR_ival( struct sql_str *);
+static struct expr * EXPR_sval( struct sql_str *);
+static struct expr * EXPR_wildcard();
+
+%}
+
+%pure-parser
+
+%union
+{
+ struct sql_str str;
+ LPWSTR string;
+ string_list *column_list;
+ value_list *val_list;
+ MSIVIEW *query;
+ struct expr *expr;
+ USHORT column_type;
+ create_col_info *column_info;
+ column_assignment update_col_info;
+}
+
+%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC
+%token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY
+%token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN
+%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT
+%token TK_CONSTRAINT TK_COPY TK_CREATE
+%token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC
+%token TK_DISTINCT TK_DOT TK_DROP TK_EACH
+%token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN
+%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FROM TK_FUNCTION
+%token TK_GE TK_GLOB TK_GROUP TK_GT
+%token TK_HAVING TK_HOLD
+%token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY
+%token <str> TK_ID
+%token TK_INSERT TK_INSTEAD TK_INT
+%token <str> TK_INTEGER
+%token TK_INTERSECT TK_INTO TK_IS
+%token TK_ISNULL
+%token TK_JOIN TK_JOIN_KW
+%token TK_KEY
+%token TK_LE TK_LIKE TK_LIMIT TK_LONG TK_LONGCHAR TK_LP TK_LSHIFT TK_LT
+%token TK_LOCALIZABLE
+%token TK_MATCH TK_MINUS
+%token TK_NE TK_NOT TK_NOTNULL TK_NULL
+%token TK_OBJECT TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
+%token TK_PLUS TK_PRAGMA TK_PRIMARY
+%token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK
+%token TK_ROW TK_RP TK_RSHIFT
+%token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT
+%token <str> TK_STRING
+%token TK_TABLE TK_TEMP TK_THEN TK_TRANSACTION TK_TRIGGER
+%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
+%token TK_UPDATE TK_UPLUS TK_USING
+%token TK_VACUUM TK_VALUES TK_VIEW
+%token TK_WHEN TK_WHERE TK_WILDCARD
+
+/*
+ * These are extra tokens used by the lexer but never seen by the
+ * parser. We put them in a rule so that the parser generator will
+ * add them to the parse.h output file.
+ *
+ */
+%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION
+ COLUMN AGG_FUNCTION.
+
+%type <string> column table string_or_id
+%type <column_list> selcollist
+%type <query> from unorderedsel oneselect onequery onecreate oneinsert oneupdate
+%type <expr> expr val column_val const_val
+%type <column_type> column_type data_type data_type_l data_count
+%type <column_info> column_def table_def
+%type <val_list> constlist
+%type <update_col_info> column_assignment update_assign_list
+
+%%
+
+onequery:
+ oneselect
+ {
+ SQL_input* sql = (SQL_input*) info;
+ *sql->view = $1;
+ }
+ | onecreate
+ {
+ SQL_input* sql = (SQL_input*) info;
+ *sql->view = $1;
+ }
+ | oneinsert
+ {
+ SQL_input* sql = (SQL_input*) info;
+ *sql->view = $1;
+ }
+ | oneupdate
+ {
+ SQL_input* sql = (SQL_input*) info;
+ *sql->view = $1;
+ }
+ ;
+
+oneinsert:
+ TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP
+ {
+ SQL_input *sql = (SQL_input*) info;
+ MSIVIEW *insert = NULL;
+
+ INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE );
+ $$ = insert;
+ }
+ | TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMP
+ {
+ SQL_input *sql = (SQL_input*) info;
+ MSIVIEW *insert = NULL;
+
+ INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE );
+ $$ = insert;
+ }
+ ;
+
+onecreate:
+ TK_CREATE TK_TABLE table TK_LP table_def TK_RP
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *create = NULL;
+
+ if( !$5 )
+ YYABORT;
+ CREATE_CreateView( sql->db, &create, $3, $5, FALSE );
+ $$ = create;
+ }
+ | TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *create = NULL;
+
+ if( !$5 )
+ YYABORT;
+ CREATE_CreateView( sql->db, &create, $3, $5, TRUE );
+ $$ = create;
+ }
+ ;
+
+oneupdate:
+ TK_UPDATE table TK_SET update_assign_list TK_WHERE expr
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *update = NULL;
+
+ UPDATE_CreateView( sql->db, &update, $2, &$4, $6 );
+ $$ = update;
+ }
+ ;
+
+table_def:
+ column_def TK_PRIMARY TK_KEY selcollist
+ {
+ if( SQL_MarkPrimaryKeys( $1, $4 ) )
+ $$ = $1;
+ else
+ $$ = NULL;
+ }
+ ;
+
+column_def:
+ column_def TK_COMMA column column_type
+ {
+ create_col_info *ci;
+
+ for( ci = $1; ci->next; ci = ci->next )
+ ;
+
+ ci->next = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );
+ if( !ci->next )
+ {
+ /* FIXME: free $1 */
+ YYABORT;
+ }
+ ci->next->colname = $3;
+ ci->next->type = $4;
+ ci->next->next = NULL;
+
+ $$ = $1;
+ }
+ | column column_type
+ {
+ $$ = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );
+ if( ! $$ )
+ YYABORT;
+ $$->colname = $1;
+ $$->type = $2;
+ $$->next = NULL;
+ }
+ ;
+
+column_type:
+ data_type_l
+ {
+ $$ = $1 | MSITYPE_VALID;
+ }
+ | data_type_l TK_LOCALIZABLE
+ {
+ FIXME("LOCALIZABLE ignored\n");
+ $$ = $1 | MSITYPE_VALID;
+ }
+ ;
+
+data_type_l:
+ data_type
+ {
+ $$ |= MSITYPE_NULLABLE;
+ }
+ | data_type TK_NOT TK_NULL
+ {
+ $$ = $1;
+ }
+ ;
+
+data_type:
+ TK_CHAR
+ {
+ $$ = MSITYPE_STRING | 1;
+ }
+ | TK_CHAR TK_LP data_count TK_RP
+ {
+ $$ = MSITYPE_STRING | 0x400 | $3;
+ }
+ | TK_LONGCHAR
+ {
+ $$ = 2;
+ }
+ | TK_SHORT
+ {
+ $$ = 2;
+ }
+ | TK_INT
+ {
+ $$ = 2;
+ }
+ | TK_LONG
+ {
+ $$ = 4;
+ }
+ | TK_OBJECT
+ {
+ $$ = 0;
+ }
+ ;
+
+data_count:
+ TK_INTEGER
+ {
+ SQL_input* sql = (SQL_input*) info;
+ int val = SQL_getint(sql);
+ if( ( val > 255 ) || ( val < 0 ) )
+ YYABORT;
+ $$ = val;
+ }
+ ;
+
+oneselect:
+ unorderedsel TK_ORDER TK_BY selcollist
+ {
+ SQL_input* sql = (SQL_input*) info;
+
+ if( !$1 )
+ YYABORT;
+ if( $4 )
+ $$ = do_order_by( sql->db, $1, $4 );
+ else
+ $$ = $1;
+ }
+ | unorderedsel
+ ;
+
+unorderedsel:
+ TK_SELECT selcollist from
+ {
+ SQL_input* sql = (SQL_input*) info;
+ if( !$3 )
+ YYABORT;
+ if( $2 )
+ {
+ $$ = do_one_select( sql->db, $3, $2 );
+ if( !$$ )
+ YYABORT;
+ }
+ else
+ $$ = $3;
+ }
+ | TK_SELECT TK_DISTINCT selcollist from
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *view = $4;
+
+ if( !view )
+ YYABORT;
+ if( $3 )
+ {
+ view = do_one_select( sql->db, view, $3 );
+ if( !view )
+ YYABORT;
+ }
+ DISTINCT_CreateView( sql->db, & $$, view );
+ }
+ ;
+
+selcollist:
+ column
+ {
+ string_list *list;
+
+ list = HeapAlloc( GetProcessHeap(), 0, sizeof *list );
+ if( !list )
+ YYABORT;
+ list->string = $1;
+ list->next = NULL;
+
+ $$ = list;
+ TRACE("Collist %s\n",debugstr_w($$->string));
+ }
+ | column TK_COMMA selcollist
+ {
+ string_list *list;
+
+ list = HeapAlloc( GetProcessHeap(), 0, sizeof *list );
+ if( !list )
+ YYABORT;
+ list->string = $1;
+ list->next = $3;
+
+ $$ = list;
+ TRACE("From table: %s\n",debugstr_w($$->string));
+ }
+ | TK_STAR
+ {
+ $$ = NULL;
+ }
+ ;
+
+from:
+ TK_FROM table
+ {
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ $$ = NULL;
+ TRACE("From table: %s\n",debugstr_w($2));
+ r = TABLE_CreateView( sql->db, $2, & $$ );
+ if( r != ERROR_SUCCESS )
+ YYABORT;
+ }
+ | TK_FROM table TK_WHERE expr
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *view = NULL;
+ UINT r;
+
+ $$ = NULL;
+ TRACE("From table: %s\n",debugstr_w($2));
+ r = TABLE_CreateView( sql->db, $2, &view );
+ if( r != ERROR_SUCCESS )
+ YYABORT;
+ r = WHERE_CreateView( sql->db, &view, view, $4 );
+ if( r != ERROR_SUCCESS )
+ YYABORT;
+ $$ = view;
+ }
+ ;
+
+expr:
+ TK_LP expr TK_RP
+ {
+ $$ = $2;
+ }
+ | column_val TK_EQ column_val
+ {
+ $$ = EXPR_complex( $1, OP_EQ, $3 );
+ }
+ | expr TK_AND expr
+ {
+ $$ = EXPR_complex( $1, OP_AND, $3 );
+ }
+ | expr TK_OR expr
+ {
+ $$ = EXPR_complex( $1, OP_OR, $3 );
+ }
+ | column_val TK_EQ val
+ {
+ $$ = EXPR_complex( $1, OP_EQ, $3 );
+ }
+ | column_val TK_GT val
+ {
+ $$ = EXPR_complex( $1, OP_GT, $3 );
+ }
+ | column_val TK_LT val
+ {
+ $$ = EXPR_complex( $1, OP_LT, $3 );
+ }
+ | column_val TK_LE val
+ {
+ $$ = EXPR_complex( $1, OP_LE, $3 );
+ }
+ | column_val TK_GE val
+ {
+ $$ = EXPR_complex( $1, OP_GE, $3 );
+ }
+ | column_val TK_NE val
+ {
+ $$ = EXPR_complex( $1, OP_NE, $3 );
+ }
+ | column_val TK_IS TK_NULL
+ {
+ $$ = EXPR_complex( $1, OP_ISNULL, NULL );
+ }
+ | column_val TK_IS TK_NOT TK_NULL
+ {
+ $$ = EXPR_complex( $1, OP_NOTNULL, NULL );
+ }
+ ;
+
+val:
+ column_val
+ | const_val
+ ;
+
+constlist:
+ const_val
+ {
+ value_list *vals;
+
+ vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );
+ if( vals )
+ {
+ vals->val = $1;
+ vals->next = NULL;
+ }
+ $$ = vals;
+ }
+ | constlist TK_COMMA const_val
+ {
+ value_list *vals;
+
+ vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals );
+ if( vals )
+ {
+ vals->val = $3;
+ vals->next = NULL;
+ }
+ $1->next = vals;
+ $$ = $1;
+ }
+ ;
+
+update_assign_list:
+ column_assignment
+ | column_assignment TK_COMMA update_assign_list
+ {
+ $1.col_list->next = $3.col_list;
+ $1.val_list->next = $3.val_list;
+ $$ = $1;
+ }
+ ;
+
+column_assignment:
+ column TK_EQ const_val
+ {
+ $$.col_list = HeapAlloc( GetProcessHeap(), 0, sizeof *$$.col_list );
+ if( !$$.col_list )
+ YYABORT;
+ $$.col_list->string = $1;
+ $$.col_list->next = NULL;
+ $$.val_list = HeapAlloc( GetProcessHeap(), 0, sizeof *$$.val_list );
+ if( !$$.val_list )
+ YYABORT;
+ $$.val_list->val = $3;
+ $$.val_list->next = 0;
+ }
+ ;
+
+const_val:
+ TK_INTEGER
+ {
+ $$ = EXPR_ival( &$1 );
+ }
+ | TK_STRING
+ {
+ $$ = EXPR_sval( &$1 );
+ }
+ | TK_WILDCARD
+ {
+ $$ = EXPR_wildcard();
+ }
+ ;
+
+column_val:
+ column
+ {
+ $$ = EXPR_column( $1 );
+ }
+ ;
+
+column:
+ table TK_DOT string_or_id
+ {
+ $$ = $3; /* FIXME */
+ }
+ | string_or_id
+ {
+ $$ = $1;
+ }
+ ;
+
+table:
+ string_or_id
+ {
+ $$ = $1;
+ }
+ ;
+
+string_or_id:
+ TK_ID
+ {
+ $$ = SQL_getstring( &$1 );
+ }
+ | TK_STRING
+ {
+ $$ = SQL_getstring( &$1 );
+ }
+ ;
+
+%%
+
+int SQL_lex( void *SQL_lval, SQL_input *sql)
+{
+ int token;
+ struct sql_str * str = SQL_lval;
+
+ do
+ {
+ sql->n += sql->len;
+ if( ! sql->command[sql->n] )
+ return 0; /* end of input */
+
+ TRACE("string : %s\n", debugstr_w(&sql->command[sql->n]));
+ sql->len = sqliteGetToken( &sql->command[sql->n], &token );
+ if( sql->len==0 )
+ break;
+ str->data = &sql->command[sql->n];
+ str->len = sql->len;
+ }
+ while( token == TK_SPACE );
+
+ TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len));
+
+ return token;
+}
+
+LPWSTR SQL_getstring( struct sql_str *strdata)
+{
+ LPCWSTR p = strdata->data;
+ UINT len = strdata->len;
+ LPWSTR str;
+
+ /* if there's quotes, remove them */
+ if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
+ ( (p[0]=='\'') && (p[len-1]=='\'') ) )
+ {
+ p++;
+ len -= 2;
+ }
+ str = HeapAlloc( GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
+ if(!str )
+ return str;
+ memcpy(str, p, len*sizeof(WCHAR) );
+ str[len]=0;
+
+ return str;
+}
+
+INT SQL_getint( SQL_input *sql )
+{
+ LPCWSTR p = &sql->command[sql->n];
+
+ return atoiW( p );
+}
+
+int SQL_error(const char *str)
+{
+ return 0;
+}
+
+static MSIVIEW *do_one_select( MSIDATABASE *db, MSIVIEW *in,
+ string_list *columns )
+{
+ MSIVIEW *view = NULL;
+
+ SELECT_CreateView( db, &view, in, columns );
+ delete_string_list( columns );
+ if( !view )
+ ERR("Error creating select query\n");
+ return view;
+}
+
+static MSIVIEW *do_order_by( MSIDATABASE *db, MSIVIEW *in,
+ string_list *columns )
+{
+ MSIVIEW *view = NULL;
+
+ ORDER_CreateView( db, &view, in );
+ if( view )
+ {
+ string_list *x = columns;
+
+ for( x = columns; x ; x = x->next )
+ ORDER_AddColumn( view, x->string );
+ }
+ else
+ ERR("Error creating select query\n");
+ delete_string_list( columns );
+ return view;
+}
+
+static struct expr * EXPR_wildcard()
+{
+ struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_WILDCARD;
+ }
+ return e;
+}
+
+static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r )
+{
+ struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_COMPLEX;
+ e->u.expr.left = l;
+ e->u.expr.op = op;
+ e->u.expr.right = r;
+ }
+ return e;
+}
+
+static struct expr * EXPR_column( LPWSTR str )
+{
+ struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_COLUMN;
+ e->u.sval = str;
+ }
+ return e;
+}
+
+static struct expr * EXPR_ival( struct sql_str *str )
+{
+ struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_IVAL;
+ e->u.ival = atoiW( str->data );
+ }
+ return e;
+}
+
+static struct expr * EXPR_sval( struct sql_str *str )
+{
+ struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_SVAL;
+ e->u.sval = SQL_getstring( str );
+ }
+ return e;
+}
+
+void delete_expr( struct expr *e )
+{
+ if( !e )
+ return;
+ if( e->type == EXPR_COMPLEX )
+ {
+ delete_expr( e->u.expr.left );
+ delete_expr( e->u.expr.right );
+ }
+ else if( e->type == EXPR_UTF8 )
+ HeapFree( GetProcessHeap(), 0, e->u.utf8 );
+ else if( e->type == EXPR_SVAL )
+ HeapFree( GetProcessHeap(), 0, e->u.sval );
+ HeapFree( GetProcessHeap(), 0, e );
+}
+
+void delete_string_list( string_list *sl )
+{
+ while( sl )
+ {
+ string_list *t = sl->next;
+ HeapFree( GetProcessHeap(), 0, sl->string );
+ HeapFree( GetProcessHeap(), 0, sl );
+ sl = t;
+ }
+}
+
+void delete_value_list( value_list *vl )
+{
+ while( vl )
+ {
+ value_list *t = vl->next;
+ delete_expr( vl->val );
+ HeapFree( GetProcessHeap(), 0, vl );
+ vl = t;
+ }
+}
+
+static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
+ string_list *keys )
+{
+ string_list *k;
+ BOOL found = TRUE;
+
+ for( k = keys; k && found; k = k->next )
+ {
+ create_col_info *c;
+
+ found = FALSE;
+ for( c = cols; c && !found; c = c->next )
+ {
+ if( lstrcmpW( k->string, c->colname ) )
+ continue;
+ c->type |= MSITYPE_KEY;
+ found = TRUE;
+ }
+ }
+
+ return found;
+}
+
+UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
+{
+ SQL_input sql;
+ int r;
+
+ *phview = NULL;
+
+ sql.db = db;
+ sql.command = command;
+ sql.n = 0;
+ sql.len = 0;
+ sql.view = phview;
+
+ r = SQL_parse(&sql);
+
+ TRACE("Parse returned %d\n", r);
+ if( r )
+ {
+ if( *sql.view )
+ (*sql.view)->ops->delete( *sql.view );
+ *sql.view = NULL;
+ return ERROR_BAD_QUERY_SYNTAX;
+ }
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N string.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ string.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,459 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004, Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+#include <assert.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct _msistring
+{
+ UINT hash;
+ UINT refcount;
+ LPWSTR str;
+} msistring;
+
+struct string_table
+{
+ UINT maxcount; /* the number of strings */
+ UINT freeslot;
+ UINT codepage;
+ msistring *strings; /* an array of strings (in the tree) */
+};
+
+static UINT msistring_makehash( const WCHAR *str )
+{
+ UINT hash = 0;
+
+ if (str==NULL)
+ return hash;
+
+ while( *str )
+ {
+ hash ^= *str++;
+ hash *= 53;
+ hash = (hash<<5) | (hash>>27);
+ }
+ return hash;
+}
+
+string_table *msi_init_stringtable( int entries, UINT codepage )
+{
+ string_table *st;
+
+ st = HeapAlloc( GetProcessHeap(), 0, sizeof (string_table) );
+ if( !st )
+ return NULL;
+ st->strings = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof (msistring) * entries );
+ if( !st )
+ {
+ HeapFree( GetProcessHeap(), 0, st );
+ return NULL;
+ }
+ if( entries < 1 )
+ entries = 1;
+ st->maxcount = entries;
+ st->freeslot = 1;
+ st->codepage = codepage;
+
+ return st;
+}
+
+VOID msi_destroy_stringtable( string_table *st )
+{
+ UINT i;
+
+ for( i=0; i<st->maxcount; i++ )
+ {
+ if( st->strings[i].refcount )
+ HeapFree( GetProcessHeap(), 0, st->strings[i].str );
+ }
+ HeapFree( GetProcessHeap(), 0, st->strings );
+ HeapFree( GetProcessHeap(), 0, st );
+}
+
+static int st_find_free_entry( string_table *st )
+{
+ UINT i, sz;
+ msistring *p;
+
+ TRACE("%p\n", st);
+
+ if( st->freeslot )
+ {
+ for( i = st->freeslot; i < st->maxcount; i++ )
+ if( !st->strings[i].refcount )
+ return i;
+ }
+ for( i = 1; i < st->maxcount; i++ )
+ if( !st->strings[i].refcount )
+ return i;
+
+ /* dynamically resize */
+ sz = st->maxcount + 1 + st->maxcount/2;
+ p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ st->strings, sz*sizeof(msistring) );
+ if( !p )
+ return -1;
+ st->strings = p;
+ st->freeslot = st->maxcount;
+ st->maxcount = sz;
+ if( st->strings[st->freeslot].refcount )
+ ERR("oops. expected freeslot to be free...\n");
+ return st->freeslot;
+}
+
+static void st_mark_entry_used( string_table *st, UINT n )
+{
+ if( n >= st->maxcount )
+ return;
+ st->freeslot = n + 1;
+}
+
+int msi_addstring( string_table *st, int n, const CHAR *data, int len, UINT refcount )
+{
+ int sz;
+
+ if( !data )
+ return 0;
+ if( !data[0] )
+ return 0;
+ if( n > 0 )
+ {
+ if( st->strings[n].refcount )
+ return -1;
+ }
+ else
+ {
+ if( ERROR_SUCCESS == msi_string2idA( st, data, &n ) )
+ {
+ st->strings[n].refcount++;
+ return n;
+ }
+ n = st_find_free_entry( st );
+ if( n < 0 )
+ return -1;
+ }
+
+ if( n < 1 )
+ {
+ ERR("invalid index adding %s (%d)\n", debugstr_a( data ), n );
+ return -1;
+ }
+
+ /* allocate a new string */
+ if( len < 0 )
+ len = strlen(data);
+ sz = MultiByteToWideChar( st->codepage, 0, data, len, NULL, 0 );
+ st->strings[n].str = HeapAlloc( GetProcessHeap(), 0, (sz+1)*sizeof(WCHAR) );
+ if( !st->strings[n].str )
+ return -1;
+ MultiByteToWideChar( st->codepage, 0, data, len, st->strings[n].str, sz );
+ st->strings[n].str[sz] = 0;
+ st->strings[n].refcount = 1;
+ st->strings[n].hash = msistring_makehash( st->strings[n].str );
+
+ st_mark_entry_used( st, n );
+
+ return n;
+}
+
+int msi_addstringW( string_table *st, int n, const WCHAR *data, int len, UINT refcount )
+{
+ /* TRACE("[%2d] = %s\n", string_no, debugstr_an(data,len) ); */
+
+ if( !data )
+ return 0;
+ if( !data[0] )
+ return 0;
+ if( n > 0 )
+ {
+ if( st->strings[n].refcount )
+ return -1;
+ }
+ else
+ {
+ if( ERROR_SUCCESS == msi_string2idW( st, data, &n ) )
+ {
+ st->strings[n].refcount++;
+ return n;
+ }
+ n = st_find_free_entry( st );
+ if( n < 0 )
+ return -1;
+ }
+
+ if( n < 1 )
+ {
+ ERR("invalid index adding %s (%d)\n", debugstr_w( data ), n );
+ return -1;
+ }
+
+ /* allocate a new string */
+ if(len<0)
+ len = strlenW(data);
+ TRACE("%s, n = %d len = %d\n", debugstr_w(data), n, len );
+
+ st->strings[n].str = HeapAlloc( GetProcessHeap(), 0, (len+1)*sizeof(WCHAR) );
+ if( !st->strings[n].str )
+ return -1;
+ TRACE("%d\n",__LINE__);
+ memcpy( st->strings[n].str, data, len*sizeof(WCHAR) );
+ st->strings[n].str[len] = 0;
+ st->strings[n].refcount = 1;
+ st->strings[n].hash = msistring_makehash( st->strings[n].str );
+
+ st_mark_entry_used( st, n );
+
+ return n;
+}
+
+/* find the string identified by an id - return null if there's none */
+const WCHAR *msi_string_lookup_id( string_table *st, UINT id )
+{
+ static const WCHAR zero[] = { 0 };
+ if( id == 0 )
+ return zero;
+
+ if( id >= st->maxcount )
+ return NULL;
+
+ if( id && !st->strings[id].refcount )
+ return NULL;
+
+ return st->strings[id].str;
+}
+
+/*
+ * msi_id2stringW
+ *
+ * [in] st - pointer to the string table
+ * [in] id - id of the string to retrieve
+ * [out] buffer - destination of the string
+ * [in/out] sz - number of bytes available in the buffer on input
+ * number of bytes used on output
+ *
+ * The size includes the terminating nul character. Short buffers
+ * will be filled, but not nul terminated.
+ */
+UINT msi_id2stringW( string_table *st, UINT id, LPWSTR buffer, UINT *sz )
+{
+ UINT len;
+ const WCHAR *str;
+
+ TRACE("Finding string %d of %d\n", id, st->maxcount);
+
+ str = msi_string_lookup_id( st, id );
+ if( !str )
+ return ERROR_FUNCTION_FAILED;
+
+ len = strlenW( str ) + 1;
+
+ if( !buffer )
+ {
+ *sz = len;
+ return ERROR_SUCCESS;
+ }
+
+ if( *sz < len )
+ *sz = len;
+ memcpy( buffer, str, (*sz)*sizeof(WCHAR) );
+ *sz = len;
+
+ return ERROR_SUCCESS;
+}
+
+/*
+ * msi_id2stringA
+ *
+ * [in] st - pointer to the string table
+ * [in] id - id of the string to retrieve
+ * [out] buffer - destination of the UTF8 string
+ * [in/out] sz - number of bytes available in the buffer on input
+ * number of bytes used on output
+ *
+ * The size includes the terminating nul character. Short buffers
+ * will be filled, but not nul terminated.
+ */
+UINT msi_id2stringA( string_table *st, UINT id, LPSTR buffer, UINT *sz )
+{
+ UINT len;
+ const WCHAR *str;
+ int n;
+
+ TRACE("Finding string %d of %d\n", id, st->maxcount);
+
+ str = msi_string_lookup_id( st, id );
+ if( !str )
+ return ERROR_FUNCTION_FAILED;
+
+ len = WideCharToMultiByte( st->codepage, 0, str, -1, NULL, 0, NULL, NULL );
+
+ if( !buffer )
+ {
+ *sz = len;
+ return ERROR_SUCCESS;
+ }
+
+ if( len > *sz )
+ {
+ n = strlenW( str ) + 1;
+ while( n && (len > *sz) )
+ len = WideCharToMultiByte( st->codepage, 0,
+ str, --n, NULL, 0, NULL, NULL );
+ }
+ else
+ n = -1;
+
+ *sz = WideCharToMultiByte( st->codepage, 0, str, n, buffer, len, NULL, NULL );
+
+ return ERROR_SUCCESS;
+}
+
+/*
+ * msi_string2idW
+ *
+ * [in] st - pointer to the string table
+ * [in] str - string to find in the string table
+ * [out] id - id of the string, if found
+ */
+UINT msi_string2idW( string_table *st, LPCWSTR str, UINT *id )
+{
+ UINT hash;
+ UINT i, r = ERROR_INVALID_PARAMETER;
+
+ hash = msistring_makehash( str );
+ for( i=0; i<st->maxcount; i++ )
+ {
+ if ( (str == NULL && st->strings[i].str == NULL) ||
+ ( ( st->strings[i].hash == hash ) &&
+ !strcmpW( st->strings[i].str, str ) ))
+ {
+ r = ERROR_SUCCESS;
+ *id = i;
+ break;
+ }
+ }
+
+ return r;
+}
+
+UINT msi_string2idA( string_table *st, LPCSTR buffer, UINT *id )
+{
+ DWORD sz;
+ UINT r = ERROR_INVALID_PARAMETER;
+ LPWSTR str;
+
+ TRACE("Finding string %s in string table\n", debugstr_a(buffer) );
+
+ if( buffer[0] == 0 )
+ {
+ *id = 0;
+ return ERROR_SUCCESS;
+ }
+
+ sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 );
+ if( sz <= 0 )
+ return r;
+ str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof(WCHAR) );
+ if( !str )
+ return ERROR_NOT_ENOUGH_MEMORY;
+ MultiByteToWideChar( st->codepage, 0, buffer, -1, str, sz );
+
+ r = msi_string2idW( st, str, id );
+ if( str )
+ HeapFree( GetProcessHeap(), 0, str );
+
+ return r;
+}
+
+UINT msi_strcmp( string_table *st, UINT lval, UINT rval, UINT *res )
+{
+ const WCHAR *l_str, *r_str;
+
+ l_str = msi_string_lookup_id( st, lval );
+ if( !l_str )
+ return ERROR_INVALID_PARAMETER;
+
+ r_str = msi_string_lookup_id( st, rval );
+ if( !r_str )
+ return ERROR_INVALID_PARAMETER;
+
+ /* does this do the right thing for all UTF-8 strings? */
+ *res = strcmpW( l_str, r_str );
+
+ return ERROR_SUCCESS;
+}
+
+UINT msi_string_count( string_table *st )
+{
+ return st->maxcount;
+}
+
+UINT msi_id_refcount( string_table *st, UINT i )
+{
+ if( i >= st->maxcount )
+ return 0;
+ return st->strings[i].refcount;
+}
+
+UINT msi_string_totalsize( string_table *st, UINT *total )
+{
+ UINT size = 0, i, len;
+
+ if( st->strings[0].str || st->strings[0].refcount )
+ ERR("oops. element 0 has a string\n");
+ *total = 0;
+ for( i=1; i<st->maxcount; i++ )
+ {
+ if( st->strings[i].str )
+ {
+ TRACE("[%u] = %s\n", i, debugstr_w(st->strings[i].str));
+ len = WideCharToMultiByte( st->codepage, 0,
+ st->strings[i].str, -1, NULL, 0, NULL, NULL);
+ if( len )
+ len--;
+ size += len;
+ *total = (i+1);
+ }
+ }
+ TRACE("%u/%u strings %u bytes codepage %x\n", *total, st->maxcount, size, st->codepage );
+ return size;
+}
+
+UINT msi_string_get_codepage( string_table *st )
+{
+ return st->codepage;
+}
reactos/lib/msi
diff -N suminfo.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ suminfo.c 13 Dec 2004 16:18:26 -0000 1.2.2.1
@@ -0,0 +1,234 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+
+#define PRSPEC_PROPID (1)
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winnls.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+#include "objidl.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+static const WCHAR szSumInfo[] = { 5 ,'S','u','m','m','a','r','y',
+ 'I','n','f','o','r','m','a','t','i','o','n',0 };
+
+static void MSI_CloseSummaryInfo( MSIOBJECTHDR *arg )
+{
+ MSISUMMARYINFO *suminfo = (MSISUMMARYINFO *) arg;
+ IPropertyStorage_Release( suminfo->propstg );
+}
+
+UINT WINAPI MsiGetSummaryInformationA(MSIHANDLE hDatabase,
+ LPCSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
+{
+ LPWSTR szwDatabase = NULL;
+ UINT ret;
+
+ TRACE("%ld %s %d %p\n", hDatabase, debugstr_a(szDatabase),
+ uiUpdateCount, phSummaryInfo);
+
+ if( szDatabase )
+ {
+ UINT len = MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, NULL, 0 );
+ szwDatabase = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
+ if( !szwDatabase )
+ return ERROR_FUNCTION_FAILED;
+ MultiByteToWideChar( CP_ACP, 0, szDatabase, -1, szwDatabase, len );
+ }
+
+ ret = MsiGetSummaryInformationW(hDatabase, szwDatabase, uiUpdateCount, phSummaryInfo);
+
+ if( szwDatabase )
+ HeapFree( GetProcessHeap(), 0, szwDatabase );
+
+ return ret;
+}
+
+UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
+ LPCWSTR szDatabase, UINT uiUpdateCount, MSIHANDLE *phSummaryInfo)
+{
+ HRESULT r;
+ MSIHANDLE handle;
+ MSISUMMARYINFO *suminfo;
+ MSIDATABASE *db;
+ UINT ret = ERROR_SUCCESS;
+ IPropertySetStorage *psstg = NULL;
+ IPropertyStorage *ps = NULL;
+ DWORD grfMode;
+
+ TRACE("%ld %s %d %p\n", hDatabase, debugstr_w(szDatabase),
+ uiUpdateCount, phSummaryInfo);
+
+ if( !phSummaryInfo )
+ return ERROR_INVALID_PARAMETER;
+
+ if( szDatabase )
+ {
+ UINT res;
+
+ res = MSI_OpenDatabaseW(szDatabase, NULL, &db);
+ if( res != ERROR_SUCCESS )
+ return res;
+ }
+ else
+ {
+ db = msihandle2msiinfo(hDatabase, MSIHANDLETYPE_DATABASE);
+ if( !db )
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ r = IStorage_QueryInterface( db->storage,
+ &IID_IPropertySetStorage, (LPVOID)&psstg);
+ if( FAILED( r ) )
+ {
+ ERR("IStorage -> IPropertySetStorage failed\n");
+ if (db)
+ msiobj_release(&db->hdr);
+ return ERROR_FUNCTION_FAILED;
+ }
+ ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
+
+ grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
+
+ r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );
+ if( FAILED( r ) )
+ {
+ ERR("failed to get IPropertyStorage r=%08lx\n",r);
+ ret = ERROR_FUNCTION_FAILED;
+ goto end;
+ }
+
+ suminfo = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO,
+ sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
+ if( !suminfo )
+ {
+ ret = ERROR_FUNCTION_FAILED;
+ goto end;
+ }
+
+ IPropertyStorage_AddRef(ps);
+ suminfo->propstg = ps;
+ handle = alloc_msihandle( &suminfo->hdr );
+ if( handle )
+ *phSummaryInfo = handle;
+ else
+ ret = ERROR_FUNCTION_FAILED;
+ msiobj_release( &suminfo->hdr );
+
+end:
+ if( ps )
+ IPropertyStorage_Release(ps);
+ if( psstg )
+ IPropertySetStorage_Release(psstg);
+ if (db)
+ msiobj_release(&db->hdr);
+
+ return ret;
+}
+
+UINT WINAPI MsiSummaryInfoGetPropertyCount(MSIHANDLE hSummaryInfo, UINT *pCount)
+{
+ MSISUMMARYINFO *suminfo;
+
+ FIXME("%ld %p\n",hSummaryInfo, pCount);
+
+ suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
+ if( !suminfo )
+ return ERROR_INVALID_HANDLE;
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+UINT WINAPI MsiSummaryInfoGetPropertyA(
+ MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
+ FILETIME *pftValue, LPSTR szValueBuf, DWORD *pcchValueBuf)
+{
+ MSISUMMARYINFO *suminfo;
+ HRESULT r;
+ PROPSPEC spec;
+ PROPVARIANT var;
+
+ TRACE("%ld %d %p %p %p %p %p\n",
+ hSummaryInfo, uiProperty, puiDataType, piValue,
+ pftValue, szValueBuf, pcchValueBuf);
+
+ suminfo = msihandle2msiinfo( hSummaryInfo, MSIHANDLETYPE_SUMMARYINFO );
+ if( !suminfo )
+ return ERROR_INVALID_HANDLE;
+
+ spec.ulKind = PRSPEC_PROPID;
+ spec.u.propid = uiProperty;
+
+ r = IPropertyStorage_ReadMultiple( suminfo->propstg, 1, &spec, &var);
+ if( FAILED(r) )
+ return ERROR_FUNCTION_FAILED;
+
+ if( puiDataType )
+ *puiDataType = var.vt;
+
+ switch( var.vt )
+ {
+ case VT_I4:
+ if( piValue )
+ *piValue = var.u.lVal;
+ break;
+ case VT_LPSTR:
+ if( pcchValueBuf && szValueBuf )
+ {
+ lstrcpynA(szValueBuf, var.u.pszVal, *pcchValueBuf );
+ *pcchValueBuf = lstrlenA( var.u.pszVal );
+ }
+ break;
+ case VT_FILETIME:
+ if( pftValue )
+ memcpy(pftValue, &var.u.filetime, sizeof (FILETIME) );
+ break;
+ case VT_EMPTY:
+ break;
+ default:
+ FIXME("Unknown property variant type\n");
+ break;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+UINT WINAPI MsiSummaryInfoGetPropertyW(
+ MSIHANDLE hSummaryInfo, UINT uiProperty, UINT *puiDataType, INT *piValue,
+ FILETIME *pftValue, LPWSTR szValueBuf, DWORD *pcchValueBuf)
+{
+ FIXME("%ld %d %p %p %p %p %p\n",
+ hSummaryInfo, uiProperty, puiDataType, piValue,
+ pftValue, szValueBuf, pcchValueBuf);
+
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
reactos/lib/msi
diff -N table.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ table.c 13 Dec 2004 16:18:26 -0000 1.3.2.1
@@ -0,0 +1,1425 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#define COBJMACROS
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "wine/unicode.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+typedef struct tagMSICOLUMNINFO
+{
+ LPWSTR tablename;
+ UINT number;
+ LPWSTR colname;
+ UINT type;
+ UINT offset;
+} MSICOLUMNINFO;
+
+struct tagMSITABLE
+{
+ USHORT **data;
+ UINT ref_count;
+ UINT row_count;
+ struct tagMSITABLE *next;
+ struct tagMSITABLE *prev;
+ WCHAR name[1];
+};
+
+#define MAX_STREAM_NAME 0x1f
+
+static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name,
+ MSICOLUMNINFO **pcols, UINT *pcount );
+static UINT get_tablecolumns( MSIDATABASE *db,
+ LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz);
+
+static inline UINT bytes_per_column( MSICOLUMNINFO *col )
+{
+ if( col->type & MSITYPE_STRING )
+ return 2;
+ if( (col->type & 0xff) > 4 )
+ ERR("Invalid column size!\n");
+ return col->type & 0xff;
+}
+
+static int utf2mime(int x)
+{
+ if( (x>='0') && (x<='9') )
+ return x-'0';
+ if( (x>='A') && (x<='Z') )
+ return x-'A'+10;
+ if( (x>='a') && (x<='z') )
+ return x-'a'+10+26;
+ if( x=='.' )
+ return 10+26+26;
+ if( x=='_' )
+ return 10+26+26+1;
+ return -1;
+}
+
+static LPWSTR encode_streamname(BOOL bTable, LPCWSTR in)
+{
+ DWORD count = MAX_STREAM_NAME;
+ DWORD ch, next;
+ LPWSTR out, p;
+
+ if( !bTable )
+ count = strlenW( in )+2;
+ out = HeapAlloc( GetProcessHeap(), 0, count*sizeof(WCHAR) );
+ p = out;
+
+ if( bTable )
+ {
+ *p++ = 0x4840;
+ count --;
+ }
+ while( count -- )
+ {
+ ch = *in++;
+ if( !ch )
+ {
+ *p = ch;
+ return out;
+ }
+ if( ( ch < 0x80 ) && ( utf2mime(ch) >= 0 ) )
+ {
+ ch = utf2mime(ch) + 0x4800;
+ next = *in;
+ if( next && (next<0x80) )
+ {
+ next = utf2mime(next);
+ if( next >= 0 )
+ {
+ next += 0x3ffffc0;
+ ch += (next<<6);
+ in++;
+ }
+ }
+ }
+ *p++ = ch;
+ }
+ ERR("Failed to encode stream name (%s)\n",debugstr_w(in));
+ HeapFree( GetProcessHeap(), 0, out );
+ return NULL;
+}
+
+static int mime2utf(int x)
+{
+ if( x<10 )
+ return x + '0';
+ if( x<(10+26))
+ return x - 10 + 'A';
+ if( x<(10+26+26))
+ return x - 10 - 26 + 'a';
+ if( x == (10+26+26) )
+ return '.';
+ return '_';
+}
+
+static BOOL decode_streamname(LPWSTR in, LPWSTR out)
+{
+ WCHAR ch;
+ DWORD count = 0;
+
+ while ( (ch = *in++) )
+ {
+ if( (ch >= 0x3800 ) && (ch < 0x4840 ) )
+ {
+ if( ch >= 0x4800 )
+ ch = mime2utf(ch-0x4800);
+ else
+ {
+ ch -= 0x3800;
+ *out++ = mime2utf(ch&0x3f);
+ count++;
+ ch = mime2utf((ch>>6)&0x3f);
+ }
+ }
+ *out++ = ch;
+ count++;
+ }
+ *out = 0;
+ return count;
+}
+
+void enum_stream_names( IStorage *stg )
+{
+ IEnumSTATSTG *stgenum = NULL;
+ HRESULT r;
+ STATSTG stat;
+ ULONG n, count;
+ WCHAR name[0x40];
+
+ r = IStorage_EnumElements( stg, 0, NULL, 0, &stgenum );
+ if( FAILED( r ) )
+ return;
+
+ n = 0;
+ while( 1 )
+ {
+ count = 0;
+ r = IEnumSTATSTG_Next( stgenum, 1, &stat, &count );
+ if( FAILED( r ) || !count )
+ break;
+ decode_streamname( stat.pwcsName, name );
+ ERR("stream %2ld -> %s %s\n", n,
+ debugstr_w(stat.pwcsName), debugstr_w(name) );
+ n++;
+ }
+
+ IEnumSTATSTG_Release( stgenum );
+}
+
+static UINT read_stream_data( IStorage *stg, LPCWSTR stname,
+ USHORT **pdata, UINT *psz )
+{
+ HRESULT r;
+ UINT ret = ERROR_FUNCTION_FAILED;
+ VOID *data;
+ ULONG sz, count;
+ IStream *stm = NULL;
+ STATSTG stat;
+ LPWSTR encname;
+
+ encname = encode_streamname(TRUE, stname);
+
+ TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
+
+ r = IStorage_OpenStream(stg, encname, NULL,
+ STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stm);
+ HeapFree( GetProcessHeap(), 0, encname );
+ if( FAILED( r ) )
+ {
+ WARN("open stream failed r = %08lx - empty table?\n",r);
+ return ret;
+ }
+
+ r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
+ if( FAILED( r ) )
+ {
+ ERR("open stream failed r = %08lx!\n",r);
+ goto end;
+ }
+
+ if( stat.cbSize.QuadPart >> 32 )
+ {
+ ERR("Too big!\n");
+ goto end;
+ }
+
+ sz = stat.cbSize.QuadPart;
+ data = HeapAlloc( GetProcessHeap(), 0, sz );
+ if( !data )
+ {
+ ERR("couldn't allocate memory r=%08lx!\n",r);
+ ret = ERROR_NOT_ENOUGH_MEMORY;
+ goto end;
+ }
+
+ r = IStream_Read(stm, data, sz, &count );
+ if( FAILED( r ) || ( count != sz ) )
+ {
+ HeapFree( GetProcessHeap(), 0, data );
+ ERR("read stream failed r = %08lx!\n",r);
+ goto end;
+ }
+
+ *pdata = data;
+ *psz = sz;
+ ret = ERROR_SUCCESS;
+
+end:
+ IStream_Release( stm );
+
+ return ret;
+}
+
+UINT db_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
+{
+ LPWSTR encname;
+ HRESULT r;
+
+ encname = encode_streamname(FALSE, stname);
+
+ TRACE("%s -> %s\n",debugstr_w(stname),debugstr_w(encname));
+
+ r = IStorage_OpenStream(db->storage, encname, NULL,
+ STGM_READ | STGM_SHARE_EXCLUSIVE, 0, stm);
+ HeapFree( GetProcessHeap(), 0, encname );
+ if( FAILED( r ) )
+ {
+ WARN("open stream failed r = %08lx - empty table?\n",r);
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+UINT read_raw_stream_data( MSIDATABASE *db, LPCWSTR stname,
+ USHORT **pdata, UINT *psz )
+{
+ HRESULT r;
+ UINT ret = ERROR_FUNCTION_FAILED;
+ VOID *data;
+ ULONG sz, count;
+ IStream *stm = NULL;
+ STATSTG stat;
+
+ r = db_get_raw_stream( db, stname, &stm );
+ if( r != ERROR_SUCCESS)
+ return ret;
+ r = IStream_Stat(stm, &stat, STATFLAG_NONAME );
+ if( FAILED( r ) )
+ {
+ ERR("open stream failed r = %08lx!\n",r);
+ goto end;
+ }
+
+ if( stat.cbSize.QuadPart >> 32 )
+ {
+ ERR("Too big!\n");
+ goto end;
+ }
+
+ sz = stat.cbSize.QuadPart;
+ data = HeapAlloc( GetProcessHeap(), 0, sz );
+ if( !data )
+ {
+ ERR("couldn't allocate memory r=%08lx!\n",r);
+ ret = ERROR_NOT_ENOUGH_MEMORY;
+ goto end;
+ }
+
+ r = IStream_Read(stm, data, sz, &count );
+ if( FAILED( r ) || ( count != sz ) )
+ {
+ HeapFree( GetProcessHeap(), 0, data );
+ ERR("read stream failed r = %08lx!\n",r);
+ goto end;
+ }
+
+ *pdata = data;
+ *psz = sz;
+ ret = ERROR_SUCCESS;
+
+end:
+ IStream_Release( stm );
+
+ return ret;
+}
+
+static UINT write_stream_data( IStorage *stg, LPCWSTR stname,
+ LPVOID data, UINT sz )
+{
+ HRESULT r;
+ UINT ret = ERROR_FUNCTION_FAILED;
+ ULONG count;
+ IStream *stm = NULL;
+ ULARGE_INTEGER size;
+ LARGE_INTEGER pos;
+ LPWSTR encname;
+
+ encname = encode_streamname(TRUE, stname );
+ r = IStorage_OpenStream( stg, encname, NULL,
+ STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &stm);
+ HeapFree( GetProcessHeap(), 0, encname );
+ if( FAILED(r) )
+ {
+ r = IStorage_CreateStream( stg, encname,
+ STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+ }
+ if( FAILED( r ) )
+ {
+ ERR("open stream failed r = %08lx\n",r);
+ return ret;
+ }
+
+ size.QuadPart = sz;
+ r = IStream_SetSize( stm, size );
+ if( FAILED( r ) )
+ {
+ ERR("Failed to SetSize\n");
+ goto end;
+ }
+
+ pos.QuadPart = 0;
+ r = IStream_Seek( stm, pos, STREAM_SEEK_SET, NULL );
+ if( FAILED( r ) )
+ {
+ ERR("Failed to Seek\n");
+ goto end;
+ }
+
+ r = IStream_Write(stm, data, sz, &count );
+ if( FAILED( r ) || ( count != sz ) )
+ {
+ ERR("Failed to Write\n");
+ goto end;
+ }
+
+ ret = ERROR_SUCCESS;
+
+end:
+ IStream_Release( stm );
+
+ return ret;
+}
+
+UINT read_table_from_storage( MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+{
+ MSITABLE *t;
+ USHORT *rawdata = NULL;
+ UINT rawsize = 0, r, i, j, row_size = 0, num_cols = 0;
+ MSICOLUMNINFO *cols, *last_col;
+
+ TRACE("%s\n",debugstr_w(name));
+
+ /* non-existing tables should be interpretted as empty tables */
+ t = HeapAlloc( GetProcessHeap(), 0,
+ sizeof (MSITABLE) + lstrlenW(name)*sizeof (WCHAR) );
+ if( !t )
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ r = table_get_column_info( db, name, &cols, &num_cols );
+ if( r != ERROR_SUCCESS )
+ {
+ HeapFree( GetProcessHeap(), 0, t );
+ return r;
+ }
+ last_col = &cols[num_cols-1];
+ row_size = last_col->offset + bytes_per_column( last_col );
+
+ t->row_count = 0;
+ t->data = NULL;
+ lstrcpyW( t->name, name );
+ t->ref_count = 1;
+ *ptable = t;
+
+ /* if we can't read the table, just assume that it's empty */
+ read_stream_data( db->storage, name, &rawdata, &rawsize );
+ if( !rawdata )
+ return ERROR_SUCCESS;
+
+ TRACE("Read %d bytes\n", rawsize );
+
+ if( rawsize % row_size )
+ {
+ ERR("Table size is invalid %d/%d\n", rawsize, row_size );
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ t->row_count = rawsize / row_size;
+ t->data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ t->row_count * sizeof (USHORT*) );
+ if( !t->data )
+ return ERROR_NOT_ENOUGH_MEMORY; /* FIXME: memory leak */
+
+ /* transpose all the data */
+ TRACE("Transposing data from %d columns\n", t->row_count );
+ for( i=0; i<t->row_count; i++ )
+ {
+ t->data[i] = HeapAlloc( GetProcessHeap(), 0, row_size );
+ if( !t->data[i] )
+ return ERROR_NOT_ENOUGH_MEMORY; /* FIXME: memory leak */
+ for( j=0; j<num_cols; j++ )
+ {
+ UINT ofs = cols[j].offset/2;
+ UINT n = bytes_per_column( &cols[j] );
+
+ switch( n )
+ {
+ case 2:
+ t->data[i][ofs] = rawdata[ofs*t->row_count + i ];
+ break;
+ case 4:
+ t->data[i][ofs] = rawdata[ofs*t->row_count + i ];
+ t->data[i][ofs+1] = rawdata[ofs*t->row_count + i + 1];
+ break;
+ default:
+ ERR("oops - unknown column width %d\n", n);
+ return ERROR_FUNCTION_FAILED;
+ }
+ }
+ }
+
+ HeapFree( GetProcessHeap(), 0, cols );
+ HeapFree( GetProcessHeap(), 0, rawdata );
+
+ return ERROR_SUCCESS;
+}
+
+/* add this table to the list of cached tables in the database */
+void add_table(MSIDATABASE *db, MSITABLE *table)
+{
+ table->next = db->first_table;
+ table->prev = NULL;
+ if( db->first_table )
+ db->first_table->prev = table;
+ else
+ db->last_table = table;
+ db->first_table = table;
+}
+
+/* remove from the list of cached tables */
+void remove_table( MSIDATABASE *db, MSITABLE *table )
+{
+ if( table->next )
+ table->next->prev = table->prev;
+ else
+ db->last_table = table->prev;
+ if( table->prev )
+ table->prev->next = table->next;
+ else
+ db->first_table = table->next;
+ table->next = NULL;
+ table->prev = NULL;
+}
+
+void release_table( MSIDATABASE *db, MSITABLE *table )
+{
+ if( !table->ref_count )
+ ERR("Trying to destroy table with refcount 0\n");
+ table->ref_count --;
+ if( !table->ref_count )
+ {
+ remove_table( db, table );
+ HeapFree( GetProcessHeap(), 0, table->data );
+ HeapFree( GetProcessHeap(), 0, table );
+ TRACE("Destroyed table %s\n", debugstr_w(table->name));
+ }
+}
+
+void free_cached_tables( MSIDATABASE *db )
+{
+ while( db->first_table )
+ {
+ MSITABLE *t = db->first_table;
+
+ if ( --t->ref_count )
+ ERR("table ref count not zero for %s\n", debugstr_w(t->name));
+ remove_table( db, t );
+ HeapFree( GetProcessHeap(), 0, t->data );
+ HeapFree( GetProcessHeap(), 0, t );
+ }
+}
+
+UINT find_cached_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+{
+ MSITABLE *t;
+
+ for( t = db->first_table; t; t=t->next )
+ {
+ if( !lstrcmpW( name, t->name ) )
+ {
+ *ptable = t;
+ return ERROR_SUCCESS;
+ }
+ }
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO **pcols, UINT *pcount )
+{
+ UINT r, column_count;
+ MSICOLUMNINFO *columns;
+
+ /* get the number of columns in this table */
+ column_count = 0;
+ r = get_tablecolumns( db, name, NULL, &column_count );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* if there's no columns, there's no table */
+ if( column_count == 0 )
+ return ERROR_INVALID_PARAMETER;
+
+ TRACE("Table %s found\n", debugstr_w(name) );
+
+ columns = HeapAlloc( GetProcessHeap(), 0, column_count*sizeof (MSICOLUMNINFO));
+ if( !columns )
+ return ERROR_FUNCTION_FAILED;
+
+ r = get_tablecolumns( db, name, columns, &column_count );
+ if( r != ERROR_SUCCESS )
+ {
+ HeapFree( GetProcessHeap(), 0, columns );
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ *pcols = columns;
+ *pcount = column_count;
+
+ return r;
+}
+
+UINT get_table(MSIDATABASE *db, LPCWSTR name, MSITABLE **ptable)
+{
+ UINT r;
+
+ *ptable = NULL;
+
+ /* first, see if the table is cached */
+ r = find_cached_table( db, name, ptable );
+ if( r == ERROR_SUCCESS )
+ {
+ (*ptable)->ref_count++;
+ return r;
+ }
+
+ r = read_table_from_storage( db, name, ptable );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* add the table to the list */
+ add_table( db, *ptable );
+ (*ptable)->ref_count++;
+
+ return ERROR_SUCCESS;
+}
+
+UINT save_table( MSIDATABASE *db, MSITABLE *t )
+{
+ USHORT *rawdata = NULL, *p;
+ UINT rawsize, r, i, j, row_size, num_cols = 0;
+ MSICOLUMNINFO *cols, *last_col;
+
+ TRACE("Saving %s\n", debugstr_w( t->name ) );
+
+ r = table_get_column_info( db, t->name, &cols, &num_cols );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ last_col = &cols[num_cols-1];
+ row_size = last_col->offset + bytes_per_column( last_col );
+
+ rawsize = t->row_count * row_size;
+ rawdata = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, rawsize );
+ if( !rawdata )
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ p = rawdata;
+ for( i=0; i<num_cols; i++ )
+ {
+ for( j=0; j<t->row_count; j++ )
+ {
+ UINT offset = cols[i].offset;
+
+ *p++ = t->data[j][offset/2];
+ if( 4 == bytes_per_column( &cols[i] ) )
+ *p++ = t->data[j][offset/2+1];
+ }
+ }
+
+ TRACE("writing %d bytes\n", rawsize);
+ r = write_stream_data( db->storage, t->name, rawdata, rawsize );
+
+ HeapFree( GetProcessHeap(), 0, rawdata );
+
+ return r;
+}
+
+HRESULT init_string_table( IStorage *stg )
+{
+ HRESULT r;
+ static const WCHAR szStringData[] = {
+ '_','S','t','r','i','n','g','D','a','t','a',0 };
+ static const WCHAR szStringPool[] = {
+ '_','S','t','r','i','n','g','P','o','o','l',0 };
+ USHORT zero[2] = { 0, 0 };
+ ULONG count = 0;
+ IStream *stm = NULL;
+ LPWSTR encname;
+
+ encname = encode_streamname(TRUE, szStringPool );
+
+ /* create the StringPool stream... add the zero string to it*/
+ r = IStorage_CreateStream( stg, encname,
+ STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+ HeapFree( GetProcessHeap(), 0, encname );
+ if( r )
+ {
+ TRACE("Failed\n");
+ return r;
+ }
+
+ r = IStream_Write(stm, zero, sizeof zero, &count );
+ IStream_Release( stm );
+
+ if( FAILED( r ) || ( count != sizeof zero ) )
+ {
+ TRACE("Failed\n");
+ return E_FAIL;
+ }
+
+ /* create the StringData stream... make it zero length */
+ encname = encode_streamname(TRUE, szStringData );
+ r = IStorage_CreateStream( stg, encname,
+ STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm);
+ HeapFree( GetProcessHeap(), 0, encname );
+ if( r )
+ {
+ TRACE("Failed\n");
+ return E_FAIL;
+ }
+ IStream_Release( stm );
+
+ return r;
+}
+
+UINT load_string_table( MSIDATABASE *db )
+{
+ CHAR *data;
+ USHORT *pool;
+ UINT r, ret = ERROR_FUNCTION_FAILED, datasize = 0, poolsize = 0, codepage;
+ DWORD i, count, offset, len, n;
+ static const WCHAR szStringData[] = {
+ '_','S','t','r','i','n','g','D','a','t','a',0 };
+ static const WCHAR szStringPool[] = {
+ '_','S','t','r','i','n','g','P','o','o','l',0 };
+
+ if( db->strings )
+ {
+ msi_destroy_stringtable( db->strings );
+ db->strings = NULL;
+ }
+
+ r = read_stream_data( db->storage, szStringPool, &pool, &poolsize );
+ if( r != ERROR_SUCCESS)
+ goto end;
+ r = read_stream_data( db->storage, szStringData, (USHORT**)&data, &datasize );
+ if( r != ERROR_SUCCESS)
+ goto end;
+
+ count = poolsize/4;
+ if( poolsize > 4 )
+ codepage = pool[0] | ( pool[1] << 16 );
+ else
+ codepage = CP_ACP;
+ db->strings = msi_init_stringtable( count, codepage );
+
+ offset = 0;
+ for( i=1; i<count; i++ )
+ {
+ len = pool[i*2];
+ n = msi_addstring( db->strings, i, data+offset, len, pool[i*2+1] );
+ if( n != i )
+ ERR("Failed to add string %ld\n", i );
+ offset += len;
+ }
+
+ TRACE("Loaded %ld strings\n", count);
+
+ ret = ERROR_SUCCESS;
+
+end:
+ if( pool )
+ HeapFree( GetProcessHeap(), 0, pool );
+ if( data )
+ HeapFree( GetProcessHeap(), 0, data );
+
+ return ret;
+}
+
+UINT save_string_table( MSIDATABASE *db )
+{
+ UINT i, count, datasize, poolsize, sz, used, r, codepage;
+ UINT ret = ERROR_FUNCTION_FAILED;
+ static const WCHAR szStringData[] = {
+ '_','S','t','r','i','n','g','D','a','t','a',0 };
+ static const WCHAR szStringPool[] = {
+ '_','S','t','r','i','n','g','P','o','o','l',0 };
+ CHAR *data = NULL;
+ USHORT *pool = NULL;
+
+ TRACE("\n");
+
+ /* construct the new table in memory first */
+ datasize = msi_string_totalsize( db->strings, &count );
+ poolsize = count*2*sizeof(USHORT);
+
+ pool = HeapAlloc( GetProcessHeap(), 0, poolsize );
+ if( ! pool )
+ {
+ ERR("Failed to alloc pool %d bytes\n", poolsize );
+ goto err;
+ }
+ data = HeapAlloc( GetProcessHeap(), 0, datasize );
+ if( ! data )
+ {
+ ERR("Failed to alloc data %d bytes\n", poolsize );
+ goto err;
+ }
+
+ used = 0;
+ codepage = msi_string_get_codepage( db->strings );
+ pool[0]=codepage&0xffff;
+ pool[1]=(codepage>>16);
+ for( i=1; i<count; i++ )
+ {
+ sz = datasize - used;
+ r = msi_id2stringA( db->strings, i, data+used, &sz );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("failed to fetch string\n");
+ sz = 0;
+ }
+ if( sz && (sz < (datasize - used ) ) )
+ sz--;
+ TRACE("adding %u bytes %s\n", sz, data+used );
+ pool[ i*2 ] = sz;
+ pool[ i*2 + 1 ] = msi_id_refcount( db->strings, i );
+ used += sz;
+ if( used > datasize )
+ {
+ ERR("oops overran %d >= %d\n", used, datasize);
+ goto err;
+ }
+ }
+
+ if( used != datasize )
+ {
+ ERR("oops used %d != datasize %d\n", used, datasize);
+ goto err;
+ }
+
+ /* write the streams */
+ r = write_stream_data( db->storage, szStringData, data, datasize );
+ TRACE("Wrote StringData r=%08x\n", r);
+ if( r )
+ goto err;
+ r = write_stream_data( db->storage, szStringPool, pool, poolsize );
+ TRACE("Wrote StringPool r=%08x\n", r);
+ if( r )
+ goto err;
+
+ ret = ERROR_SUCCESS;
+
+err:
+ if( data )
+ HeapFree( GetProcessHeap(), 0, data );
+ if( pool )
+ HeapFree( GetProcessHeap(), 0, pool );
+
+ return ret;
+}
+
+static LPWSTR strdupW( LPCWSTR str )
+{
+ UINT len = lstrlenW( str ) + 1;
+ LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
+ if( ret )
+ lstrcpyW( ret, str );
+ return ret;
+}
+
+/* information for default tables */
+static const WCHAR szTables[] = { '_','T','a','b','l','e','s',0 };
+static const WCHAR szTable[] = { 'T','a','b','l','e',0 };
+static const WCHAR szName[] = { 'N','a','m','e',0 };
+static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
+static const WCHAR szColumn[] = { 'C','o','l','u','m','n',0 };
+static const WCHAR szNumber[] = { 'N','u','m','b','e','r',0 };
+static const WCHAR szType[] = { 'T','y','p','e',0 };
+
+struct standard_table {
+ LPCWSTR tablename;
+ LPCWSTR columnname;
+ UINT number;
+ UINT type;
+} MSI_standard_tables[] =
+{
+ { szTables, szName, 1, MSITYPE_VALID | MSITYPE_STRING | 32},
+ { szColumns, szTable, 1, MSITYPE_VALID | MSITYPE_STRING | 32},
+ { szColumns, szNumber, 2, MSITYPE_VALID | 2},
+ { szColumns, szName, 3, MSITYPE_VALID | MSITYPE_STRING | 32},
+ { szColumns, szType, 4, MSITYPE_VALID | 2},
+};
+
+#define STANDARD_TABLE_COUNT \
+ (sizeof(MSI_standard_tables)/sizeof(struct standard_table))
+
+UINT get_defaulttablecolumns( LPCWSTR szTable, MSICOLUMNINFO *colinfo, UINT *sz)
+{
+ DWORD i, n=0;
+
+ for(i=0; i<STANDARD_TABLE_COUNT; i++)
+ {
+ if( lstrcmpW( szTable, MSI_standard_tables[i].tablename ) )
+ continue;
+ if(colinfo && (n < *sz) )
+ {
+ colinfo[n].tablename = strdupW(MSI_standard_tables[i].tablename);
+ colinfo[n].colname = strdupW(MSI_standard_tables[i].columnname);
+ colinfo[n].number = MSI_standard_tables[i].number;
+ colinfo[n].type = MSI_standard_tables[i].type;
+ /* ERR("Table %s has column %s\n",debugstr_w(colinfo[n].tablename),
+ debugstr_w(colinfo[n].colname)); */
+ if( n )
+ colinfo[n].offset = colinfo[n-1].offset
+ + bytes_per_column( &colinfo[n-1] );
+ else
+ colinfo[n].offset = 0;
+ }
+ n++;
+ if( colinfo && (n >= *sz) )
+ break;
+ }
+ *sz = n;
+ return ERROR_SUCCESS;
+}
+
+LPWSTR MSI_makestring( MSIDATABASE *db, UINT stringid)
+{
+ UINT sz=0, r;
+ LPWSTR str;
+
+ r = msi_id2stringW( db->strings, stringid, NULL, &sz );
+ if( r != ERROR_SUCCESS )
+ return NULL;
+ str = HeapAlloc( GetProcessHeap(), 0, sz*sizeof (WCHAR));
+ if( !str )
+ return str;
+ r = msi_id2stringW( db->strings, stringid, str, &sz );
+ if( r == ERROR_SUCCESS )
+ return str;
+ HeapFree( GetProcessHeap(), 0, str );
+ return NULL;
+}
+
+static UINT get_tablecolumns( MSIDATABASE *db,
+ LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz)
+{
+ UINT r, i, n=0, table_id, count, maxcount = *sz;
+ MSITABLE *table = NULL;
+ static const WCHAR szColumns[] = { '_','C','o','l','u','m','n','s',0 };
+
+ /* first check if there is a default table with that name */
+ r = get_defaulttablecolumns( szTableName, colinfo, sz );
+ if( ( r == ERROR_SUCCESS ) && *sz )
+ return r;
+
+ r = get_table( db, szColumns, &table);
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("table %s not available\n", debugstr_w(szColumns));
+ return r;
+ }
+
+ /* convert table and column names to IDs from the string table */
+ r = msi_string2idW( db->strings, szTableName, &table_id );
+ if( r != ERROR_SUCCESS )
+ {
+ release_table( db, table );
+ ERR("Couldn't find id for %s\n", debugstr_w(szTableName));
+ return r;
+ }
+
+ TRACE("Table id is %d\n", table_id);
+
+ count = table->row_count;
+ for( i=0; i<count; i++ )
+ {
+ if( table->data[ i ][ 0 ] != table_id )
+ continue;
+ if( colinfo )
+ {
+ UINT id = table->data[ i ] [ 2 ];
+ colinfo[n].tablename = MSI_makestring( db, table_id );
+ colinfo[n].number = table->data[ i ][ 1 ] - (1<<15);
+ colinfo[n].colname = MSI_makestring( db, id );
+ colinfo[n].type = table->data[ i ] [ 3 ];
+ /* this assumes that columns are in order in the table */
+ if( n )
+ colinfo[n].offset = colinfo[n-1].offset
+ + bytes_per_column( &colinfo[n-1] );
+ else
+ colinfo[n].offset = 0;
+ TRACE("table %s column %d is [%s] (%d) with type %08x "
+ "offset %d at row %d\n", debugstr_w(szTableName),
+ colinfo[n].number, debugstr_w(colinfo[n].colname),
+ id, colinfo[n].type, colinfo[n].offset, i);
+ if( n != (colinfo[n].number-1) )
+ {
+ ERR("oops. data in the _Columns table isn't in the right "
+ "order for table %s\n", debugstr_w(szTableName));
+ return ERROR_FUNCTION_FAILED;
+ }
+ }
+ n++;
+ if( colinfo && ( n >= maxcount ) )
+ break;
+ }
+ *sz = n;
+
+ release_table( db, table );
+
+ return ERROR_SUCCESS;
+}
+
+/* try to find the table name in the _Tables table */
+BOOL TABLE_Exists( MSIDATABASE *db, LPWSTR name )
+{
[truncated at 1000 lines; 429 more skipped]
reactos/lib/msi
diff -N tokenize.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tokenize.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,397 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** An tokenizer for SQL
+**
+** This file contains C code that splits an SQL input string up into
+** individual tokens and sends those tokens one-by-one over to the
+** parser for analysis.
+*/
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wine/debug.h"
+#include "winnls.h"
+#include "query.h"
+#include "sql.tab.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+/*
+** All the keywords of the SQL language are stored as in a hash
+** table composed of instances of the following structure.
+*/
+typedef struct Keyword Keyword;
+struct Keyword {
+ const char *zName; /* The keyword name */
+ int tokenType; /* The token value for this keyword */
+};
+
+/*
+** These are the keywords
+*/
+static const Keyword aKeywordTable[] = {
+ { "ABORT", TK_ABORT },
+ { "AFTER", TK_AFTER },
+ { "ALL", TK_ALL },
+ { "AND", TK_AND },
+ { "AS", TK_AS },
+ { "ASC", TK_ASC },
+ { "BEFORE", TK_BEFORE },
+ { "BEGIN", TK_BEGIN },
+ { "BETWEEN", TK_BETWEEN },
+ { "BY", TK_BY },
+ { "CASCADE", TK_CASCADE },
+ { "CASE", TK_CASE },
+ { "CHAR", TK_CHAR },
+ { "CHARACTER", TK_CHAR },
+ { "CHECK", TK_CHECK },
+ { "CLUSTER", TK_CLUSTER },
+ { "COLLATE", TK_COLLATE },
+ { "COMMIT", TK_COMMIT },
+ { "CONFLICT", TK_CONFLICT },
+ { "CONSTRAINT", TK_CONSTRAINT },
+ { "COPY", TK_COPY },
+ { "CREATE", TK_CREATE },
+ { "CROSS", TK_JOIN_KW },
+ { "DEFAULT", TK_DEFAULT },
+ { "DEFERRED", TK_DEFERRED },
+ { "DEFERRABLE", TK_DEFERRABLE },
+ { "DELETE", TK_DELETE },
+ { "DELIMITERS", TK_DELIMITERS },
+ { "DESC", TK_DESC },
+ { "DISTINCT", TK_DISTINCT },
+ { "DROP", TK_DROP },
+ { "END", TK_END },
+ { "EACH", TK_EACH },
+ { "ELSE", TK_ELSE },
+ { "EXCEPT", TK_EXCEPT },
+ { "EXPLAIN", TK_EXPLAIN },
+ { "FAIL", TK_FAIL },
+ { "FOR", TK_FOR },
+ { "FOREIGN", TK_FOREIGN },
+ { "FROM", TK_FROM },
+ { "FULL", TK_JOIN_KW },
+ { "GLOB", TK_GLOB },
+ { "GROUP", TK_GROUP },
+ { "HAVING", TK_HAVING },
+ { "HOLD", TK_HOLD },
+ { "IGNORE", TK_IGNORE },
+ { "IMMEDIATE", TK_IMMEDIATE },
+ { "IN", TK_IN },
+ { "INDEX", TK_INDEX },
+ { "INITIALLY", TK_INITIALLY },
+ { "INNER", TK_JOIN_KW },
+ { "INSERT", TK_INSERT },
+ { "INSTEAD", TK_INSTEAD },
+ { "INT", TK_INT },
+ { "INTERSECT", TK_INTERSECT },
+ { "INTO", TK_INTO },
+ { "IS", TK_IS },
+ { "ISNULL", TK_ISNULL },
+ { "JOIN", TK_JOIN },
+ { "KEY", TK_KEY },
+ { "LEFT", TK_JOIN_KW },
+ { "LIKE", TK_LIKE },
+ { "LIMIT", TK_LIMIT },
+ { "LOCALIZABLE", TK_LOCALIZABLE },
+ { "LONG", TK_LONG },
+ { "LONGCHAR", TK_LONGCHAR },
+ { "MATCH", TK_MATCH },
+ { "NATURAL", TK_JOIN_KW },
+ { "NOT", TK_NOT },
+ { "NOTNULL", TK_NOTNULL },
+ { "NULL", TK_NULL },
+ { "OBJECT", TK_OBJECT },
+ { "OF", TK_OF },
+ { "OFFSET", TK_OFFSET },
+ { "ON", TK_ON },
+ { "OR", TK_OR },
+ { "ORDER", TK_ORDER },
+ { "OUTER", TK_JOIN_KW },
+ { "PRAGMA", TK_PRAGMA },
+ { "PRIMARY", TK_PRIMARY },
+ { "RAISE", TK_RAISE },
+ { "REFERENCES", TK_REFERENCES },
+ { "REPLACE", TK_REPLACE },
+ { "RESTRICT", TK_RESTRICT },
+ { "RIGHT", TK_JOIN_KW },
+ { "ROLLBACK", TK_ROLLBACK },
+ { "ROW", TK_ROW },
+ { "SELECT", TK_SELECT },
+ { "SET", TK_SET },
+ { "SHORT", TK_SHORT },
+ { "STATEMENT", TK_STATEMENT },
+ { "TABLE", TK_TABLE },
+ { "TEMP", TK_TEMP },
+ { "TEMPORARY", TK_TEMP },
+ { "THEN", TK_THEN },
+ { "TRANSACTION", TK_TRANSACTION },
+ { "TRIGGER", TK_TRIGGER },
+ { "UNION", TK_UNION },
+ { "UNIQUE", TK_UNIQUE },
+ { "UPDATE", TK_UPDATE },
+ { "USING", TK_USING },
+ { "VACUUM", TK_VACUUM },
+ { "VALUES", TK_VALUES },
+ { "VIEW", TK_VIEW },
+ { "WHEN", TK_WHEN },
+ { "WHERE", TK_WHERE },
+};
+
+#define KEYWORD_COUNT ( sizeof aKeywordTable/sizeof (Keyword) )
+
+/*
+** This function looks up an identifier to determine if it is a
+** keyword. If it is a keyword, the token code of that keyword is
+** returned. If the input is not a keyword, TK_ID is returned.
+*/
+int sqliteKeywordCode(const WCHAR *z, int n){
+ UINT i, len;
+ char buffer[0x10];
+
+ len = WideCharToMultiByte( CP_ACP, 0, z, n, buffer, sizeof buffer, NULL, NULL );
+ for(i=0; i<len; i++)
+ buffer[i] = toupper(buffer[i]);
+ for(i=0; i<KEYWORD_COUNT; i++)
+ {
+ if(memcmp(buffer, aKeywordTable[i].zName, len))
+ continue;
+ if(strlen(aKeywordTable[i].zName) == len )
+ return aKeywordTable[i].tokenType;
+ }
+ return TK_ID;
+}
+
+
+/*
+** If X is a character that can be used in an identifier then
+** isIdChar[X] will be 1. Otherwise isIdChar[X] will be 0.
+**
+** In this implementation, an identifier can be a string of
+** alphabetic characters, digits, and "_" plus any character
+** with the high-order bit set. The latter rule means that
+** any sequence of UTF-8 characters or characters taken from
+** an extended ISO8859 character set can form an identifier.
+*/
+static const char isIdChar[] = {
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 8x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 9x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* Ax */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* Bx */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* Cx */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* Dx */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* Ex */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* Fx */
+};
+
+
+/*
+** Return the length of the token that begins at z[0]. Return
+** -1 if the token is (or might be) incomplete. Store the token
+** type in *tokenType before returning.
+*/
+int sqliteGetToken(const WCHAR *z, int *tokenType){
+ int i;
+ switch( *z ){
+ case ' ': case '\t': case '\n': case '\f': case '\r': {
+ for(i=1; isspace(z[i]); i++){}
+ *tokenType = TK_SPACE;
+ return i;
+ }
+ case '-': {
+ if( z[1]==0 ) return -1;
+ if( z[1]=='-' ){
+ for(i=2; z[i] && z[i]!='\n'; i++){}
+ *tokenType = TK_COMMENT;
+ return i;
+ }
+ *tokenType = TK_MINUS;
+ return 1;
+ }
+ case '(': {
+ if( z[1]=='+' && z[2]==')' ){
+ *tokenType = TK_ORACLE_OUTER_JOIN;
+ return 3;
+ }else{
+ *tokenType = TK_LP;
+ return 1;
+ }
+ }
+ case ')': {
+ *tokenType = TK_RP;
+ return 1;
+ }
+ case ';': {
+ *tokenType = TK_SEMI;
+ return 1;
+ }
+ case '+': {
+ *tokenType = TK_PLUS;
+ return 1;
+ }
+ case '*': {
+ *tokenType = TK_STAR;
+ return 1;
+ }
+ case '/': {
+ if( z[1]!='*' || z[2]==0 ){
+ *tokenType = TK_SLASH;
+ return 1;
+ }
+ for(i=3; z[i] && (z[i]!='/' || z[i-1]!='*'); i++){}
+ if( z[i] ) i++;
+ *tokenType = TK_COMMENT;
+ return i;
+ }
+ case '%': {
+ *tokenType = TK_REM;
+ return 1;
+ }
+ case '=': {
+ *tokenType = TK_EQ;
+ return 1 + (z[1]=='=');
+ }
+ case '<': {
+ if( z[1]=='=' ){
+ *tokenType = TK_LE;
+ return 2;
+ }else if( z[1]=='>' ){
+ *tokenType = TK_NE;
+ return 2;
+ }else if( z[1]=='<' ){
+ *tokenType = TK_LSHIFT;
+ return 2;
+ }else{
+ *tokenType = TK_LT;
+ return 1;
+ }
+ }
+ case '>': {
+ if( z[1]=='=' ){
+ *tokenType = TK_GE;
+ return 2;
+ }else if( z[1]=='>' ){
+ *tokenType = TK_RSHIFT;
+ return 2;
+ }else{
+ *tokenType = TK_GT;
+ return 1;
+ }
+ }
+ case '!': {
+ if( z[1]!='=' ){
+ *tokenType = TK_ILLEGAL;
+ return 2;
+ }else{
+ *tokenType = TK_NE;
+ return 2;
+ }
+ }
+ case '|': {
+ if( z[1]!='|' ){
+ *tokenType = TK_BITOR;
+ return 1;
+ }else{
+ *tokenType = TK_CONCAT;
+ return 2;
+ }
+ }
+ case '?': {
+ *tokenType = TK_WILDCARD;
+ return 1;
+ }
+ case ',': {
+ *tokenType = TK_COMMA;
+ return 1;
+ }
+ case '&': {
+ *tokenType = TK_BITAND;
+ return 1;
+ }
+ case '~': {
+ *tokenType = TK_BITNOT;
+ return 1;
+ }
+ case '`': case '\'': case '"': {
+ int delim = z[0];
+ for(i=1; z[i]; i++){
+ if( z[i]==delim ){
+ if( z[i+1]==delim ){
+ i++;
+ }else{
+ break;
+ }
+ }
+ }
+ if( z[i] ) i++;
+ *tokenType = TK_STRING;
+ return i;
+ }
+ case '.': {
+ if( !isdigit(z[1]) ){
+ *tokenType = TK_DOT;
+ return 1;
+ }
+ /* Fall thru into the next case */
+ }
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ *tokenType = TK_INTEGER;
+ for(i=1; isdigit(z[i]); i++){}
+ if( z[i]=='.' ){
+ i++;
+ while( isdigit(z[i]) ){ i++; }
+ *tokenType = TK_FLOAT;
+ }
+ if( (z[i]=='e' || z[i]=='E') &&
+ ( isdigit(z[i+1])
+ || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
+ )
+ ){
+ i += 2;
+ while( isdigit(z[i]) ){ i++; }
+ *tokenType = TK_FLOAT;
+ }else if( z[0]=='.' ){
+ *tokenType = TK_FLOAT;
+ }
+ return i;
+ }
+ case '[': {
+ for(i=1; z[i] && z[i-1]!=']'; i++){}
+ *tokenType = TK_ID;
+ return i;
+ }
+ default: {
+ if( !isIdChar[*z] ){
+ break;
+ }
+ for(i=1; isIdChar[z[i]]; i++){}
+ *tokenType = sqliteKeywordCode(z, i);
+ return i;
+ }
+ }
+ *tokenType = TK_ILLEGAL;
+ return 1;
+}
reactos/lib/msi
diff -N update.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ update.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,239 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have receuved a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIUPDATEVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ MSIVIEW *wv;
+ value_list *vals;
+} MSIUPDATEVIEW;
+
+static UINT UPDATE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+
+ TRACE("%p %d %d %p\n", uv, row, col, val );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+ UINT n, type, val, r, row, col_count = 0, row_count = 0;
+ MSIVIEW *wv;
+
+ TRACE("%p %p\n", uv, record );
+
+ if( !record )
+ return ERROR_FUNCTION_FAILED;
+
+ wv = uv->wv;
+ if( !wv )
+ return ERROR_FUNCTION_FAILED;
+
+ r = wv->ops->execute( wv, 0 );
+ TRACE("tv execute returned %x\n", r);
+ if( r )
+ return r;
+
+ r = wv->ops->get_dimensions( wv, &row_count, &col_count );
+ if( r )
+ goto err;
+
+ for( row = 0; row < row_count; row++ )
+ {
+ for( n = 1; n <= col_count; n++ )
+ {
+ r = wv->ops->get_column_info( wv, n, NULL, &type );
+ if( r )
+ break;
+
+ if( type & MSITYPE_STRING )
+ {
+ const WCHAR *str = MSI_RecordGetString( record, n );
+ val = msi_addstringW( uv->db->strings, 0, str, -1, 1 );
+ }
+ else
+ {
+ val = MSI_RecordGetInteger( record, n );
+ val |= 0x8000;
+ }
+ r = wv->ops->set_int( wv, row, n, val );
+ if( r )
+ break;
+ }
+ }
+
+err:
+ return ERROR_SUCCESS;
+}
+
+
+static UINT UPDATE_close( struct tagMSIVIEW *view )
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+ MSIVIEW *wv;
+
+ TRACE("%p\n", uv);
+
+ wv = uv->wv;
+ if( !wv )
+ return ERROR_FUNCTION_FAILED;
+
+ return wv->ops->close( wv );
+}
+
+static UINT UPDATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+ MSIVIEW *wv;
+
+ TRACE("%p %p %p\n", uv, rows, cols );
+
+ wv = uv->wv;
+ if( !wv )
+ return ERROR_FUNCTION_FAILED;
+
+ return wv->ops->get_dimensions( wv, rows, cols );
+}
+
+static UINT UPDATE_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+ MSIVIEW *wv;
+
+ TRACE("%p %d %p %p\n", uv, n, name, type );
+
+ wv = uv->wv;
+ if( !wv )
+ return ERROR_FUNCTION_FAILED;
+
+ return wv->ops->get_column_info( wv, n, name, type );
+}
+
+static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+
+ TRACE("%p %d %ld\n", uv, eModifyMode, hrec );
+
+ return ERROR_FUNCTION_FAILED;
+}
+
+static UINT UPDATE_delete( struct tagMSIVIEW *view )
+{
+ MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
+ MSIVIEW *wv;
+
+ TRACE("%p\n", uv );
+
+ wv = uv->wv;
+ if( wv )
+ wv->ops->delete( wv );
+ delete_value_list( uv->vals );
+ msiobj_release( &uv->db->hdr );
+ HeapFree( GetProcessHeap(), 0, uv );
+
+ return ERROR_SUCCESS;
+}
+
+
+static MSIVIEWOPS update_ops =
+{
+ UPDATE_fetch_int,
+ NULL,
+ NULL,
+ NULL,
+ UPDATE_execute,
+ UPDATE_close,
+ UPDATE_get_dimensions,
+ UPDATE_get_column_info,
+ UPDATE_modify,
+ UPDATE_delete
+};
+
+UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
+ column_assignment *list, struct expr *expr )
+{
+ MSIUPDATEVIEW *uv = NULL;
+ UINT r;
+ MSIVIEW *tv = NULL, *sv = NULL, *wv = NULL;
+
+ TRACE("%p\n", uv );
+
+ r = TABLE_CreateView( db, table, &tv );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* add conditions first */
+ r = WHERE_CreateView( db, &wv, tv, expr );
+ if( r != ERROR_SUCCESS )
+ {
+ if( sv )
+ sv->ops->delete( tv );
+ return r;
+ }
+
+ /* then select the columns we want */
+ r = SELECT_CreateView( db, &sv, wv, list->col_list );
+ if( r != ERROR_SUCCESS )
+ {
+ if( tv )
+ tv->ops->delete( sv );
+ return r;
+ }
+
+ uv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *uv );
+ if( !uv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ uv->view.ops = &update_ops;
+ msiobj_addref( &db->hdr );
+ uv->db = db;
+ uv->vals = list->val_list;
+ uv->wv = sv;
+ *view = (MSIVIEW*) uv;
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N version.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ version.rc 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2004 Christian Costa
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine MSI dll"
+#define WINE_FILENAME_STR "msi.dll"
+#define WINE_FILEVERSION 2,0,2600,0
+#define WINE_FILEVERSION_STR "2.0.2600.0"
+#define WINE_PRODUCTVERSION 2,0,2600,0
+#define WINE_PRODUCTVERSION_STR "2.0.2600.0"
+
+#include "wine/wine_common_ver.rc"
reactos/lib/msi
diff -N where.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ where.c 13 Dec 2004 16:18:26 -0000 1.1.2.1
@@ -0,0 +1,471 @@
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "objbase.h"
+#include "objidl.h"
+#include "msipriv.h"
+#include "winnls.h"
+
+#include "query.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+
+/* below is the query interface to a table */
+
+typedef struct tagMSIWHEREVIEW
+{
+ MSIVIEW view;
+ MSIDATABASE *db;
+ MSIVIEW *table;
+ UINT row_count;
+ UINT *reorder;
+ struct expr *cond;
+} MSIWHEREVIEW;
+
+static UINT WHERE_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %d %d %p\n", wv, row, col, val );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( row > wv->row_count )
+ return ERROR_NO_MORE_ITEMS;
+
+ row = wv->reorder[ row ];
+
+ return wv->table->ops->fetch_int( wv->table, row, col, val );
+}
+
+static UINT WHERE_fetch_stream( struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %d %d %p\n", wv, row, col, stm );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( row > wv->row_count )
+ return ERROR_NO_MORE_ITEMS;
+
+ row = wv->reorder[ row ];
+
+ return wv->table->ops->fetch_stream( wv->table, row, col, stm );
+}
+
+static UINT WHERE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %d %d %04x\n", wv, row, col, val );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( row > wv->row_count )
+ return ERROR_NO_MORE_ITEMS;
+
+ row = wv->reorder[ row ];
+
+ return wv->table->ops->set_int( wv->table, row, col, val );
+}
+
+static UINT INT_evaluate( UINT lval, UINT op, UINT rval )
+{
+ switch( op )
+ {
+ case OP_EQ:
+ return ( lval == rval );
+ case OP_AND:
+ return ( lval && rval );
+ case OP_OR:
+ return ( lval || rval );
+ case OP_GT:
+ return ( lval > rval );
+ case OP_LT:
+ return ( lval < rval );
+ case OP_LE:
+ return ( lval <= rval );
+ case OP_GE:
+ return ( lval >= rval );
+ case OP_NE:
+ return ( lval != rval );
+ case OP_ISNULL:
+ return ( !lval );
+ case OP_NOTNULL:
+ return ( lval );
+ default:
+ ERR("Unknown operator %d\n", op );
+ }
+ return 0;
+}
+
+static const WCHAR *STRING_evaluate( string_table *st,
+ MSIVIEW *table, UINT row, struct expr *expr, MSIRECORD *record )
+{
+ UINT val = 0, r;
+
+ switch( expr->type )
+ {
+ case EXPR_COL_NUMBER:
+ r = table->ops->fetch_int( table, row, expr->u.col_number, &val );
+ if( r != ERROR_SUCCESS )
+ return NULL;
+ return msi_string_lookup_id( st, val );
+
+ case EXPR_SVAL:
+ return expr->u.sval;
+
+ case EXPR_WILDCARD:
+ return MSI_RecordGetString( record, 1 );
+
+ default:
+ ERR("Invalid expression type\n");
+ break;
+ }
+ return NULL;
+}
+
+static UINT STRCMP_Evaluate( string_table *st, MSIVIEW *table, UINT row,
+ struct expr *cond, UINT *val, MSIRECORD *record )
+{
+ int sr;
+ const WCHAR *l_str, *r_str;
+
+ l_str = STRING_evaluate( st, table, row, cond->u.expr.left, record );
+ r_str = STRING_evaluate( st, table, row, cond->u.expr.right, record );
+ if( l_str == r_str )
+ sr = 0;
+ else if( l_str && ! r_str )
+ sr = 1;
+ else if( r_str && ! l_str )
+ sr = -1;
+ else
+ sr = strcmpW( l_str, r_str );
+
+ *val = ( cond->u.expr.op == OP_EQ && ( sr == 0 ) ) ||
+ ( cond->u.expr.op == OP_LT && ( sr < 0 ) ) ||
+ ( cond->u.expr.op == OP_GT && ( sr > 0 ) );
+
+ return ERROR_SUCCESS;
+}
+
+static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
+ struct expr *cond, UINT *val, MSIRECORD *record )
+{
+ UINT r, lval, rval;
+
+ if( !cond )
+ return ERROR_SUCCESS;
+
+ switch( cond->type )
+ {
+ case EXPR_COL_NUMBER:
+ return table->ops->fetch_int( table, row, cond->u.col_number, val );
+
+ case EXPR_UVAL:
+ *val = cond->u.uval;
+ return ERROR_SUCCESS;
+
+ case EXPR_COMPLEX:
+ r = WHERE_evaluate( db, table, row, cond->u.expr.left, &lval, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+ r = WHERE_evaluate( db, table, row, cond->u.expr.right, &rval, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+ *val = INT_evaluate( lval, cond->u.expr.op, rval );
+ return ERROR_SUCCESS;
+
+ case EXPR_STRCMP:
+ return STRCMP_Evaluate( db->strings, table, row, cond, val, record );
+
+ case EXPR_WILDCARD:
+ *val = MSI_RecordGetInteger( record, 1 );
+ return ERROR_SUCCESS;
+
+ default:
+ ERR("Invalid expression type\n");
+ break;
+ }
+
+ return ERROR_SUCCESS;
+
+}
+
+static UINT WHERE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+ UINT count = 0, r, val, i;
+ MSIVIEW *table = wv->table;
+
+ TRACE("%p %p\n", wv, record);
+
+ if( !table )
+ return ERROR_FUNCTION_FAILED;
+
+ r = table->ops->execute( table, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ r = table->ops->get_dimensions( table, &count, NULL );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ wv->reorder = HeapAlloc( GetProcessHeap(), 0, count*sizeof(UINT) );
+ if( !wv->reorder )
+ return ERROR_FUNCTION_FAILED;
+
+ for( i=0; i<count; i++ )
+ {
+ val = 0;
+ r = WHERE_evaluate( wv->db, table, i, wv->cond, &val, record );
+ if( r != ERROR_SUCCESS )
+ return r;
+ if( val )
+ wv->reorder[ wv->row_count ++ ] = i;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static UINT WHERE_close( struct tagMSIVIEW *view )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p\n", wv );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( wv->reorder )
+ HeapFree( GetProcessHeap(), 0, wv->reorder );
+ wv->reorder = NULL;
+
+ return wv->table->ops->close( wv->table );
+}
+
+static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %p %p\n", wv, rows, cols );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ if( rows )
+ {
+ if( !wv->reorder )
+ return ERROR_FUNCTION_FAILED;
+ *rows = wv->row_count;
+ }
+
+ return wv->table->ops->get_dimensions( wv->table, NULL, cols );
+}
+
+static UINT WHERE_get_column_info( struct tagMSIVIEW *view,
+ UINT n, LPWSTR *name, UINT *type )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %d %p %p\n", wv, n, name, type );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return wv->table->ops->get_column_info( wv->table, n, name, type );
+}
+
+static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIHANDLE hrec)
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p %d %ld\n", wv, eModifyMode, hrec );
+
+ if( !wv->table )
+ return ERROR_FUNCTION_FAILED;
+
+ return wv->table->ops->modify( wv->table, eModifyMode, hrec );
+}
+
+static UINT WHERE_delete( struct tagMSIVIEW *view )
+{
+ MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
+
+ TRACE("%p\n", wv );
+
+ if( wv->table )
+ wv->table->ops->delete( wv->table );
+
+ if( wv->reorder )
+ HeapFree( GetProcessHeap(), 0, wv->reorder );
+ wv->reorder = NULL;
+ wv->row_count = 0;
+
+ if( wv->cond )
+ delete_expr( wv->cond );
+
+ msiobj_release( &wv->db->hdr );
+ HeapFree( GetProcessHeap(), 0, wv );
+
+ return ERROR_SUCCESS;
+}
+
+
+MSIVIEWOPS where_ops =
+{
+ WHERE_fetch_int,
+ WHERE_fetch_stream,
+ WHERE_set_int,
+ NULL,
+ WHERE_execute,
+ WHERE_close,
+ WHERE_get_dimensions,
+ WHERE_get_column_info,
+ WHERE_modify,
+ WHERE_delete
+};
+
+static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr *cond,
+ UINT *valid )
+{
+ UINT r, val = 0;
+
+ switch( cond->type )
+ {
+ case EXPR_COLUMN:
+ r = VIEW_find_column( table, cond->u.column, &val );
+ if( r == ERROR_SUCCESS )
+ {
+ *valid = 1;
+ cond->type = EXPR_COL_NUMBER;
+ cond->u.col_number = val;
+ }
+ else
+ {
+ *valid = 0;
+ ERR("Couldn't find column %s\n", debugstr_w( cond->u.column ) );
+ }
+ break;
+ case EXPR_COMPLEX:
+ r = WHERE_VerifyCondition( db, table, cond->u.expr.left, valid );
+ if( r != ERROR_SUCCESS )
+ return r;
+ if( !*valid )
+ return ERROR_SUCCESS;
+ r = WHERE_VerifyCondition( db, table, cond->u.expr.right, valid );
+ if( r != ERROR_SUCCESS )
+ return r;
+
+ /* check the type of the comparison */
+ if( ( cond->u.expr.left->type == EXPR_SVAL ) ||
+ ( cond->u.expr.right->type == EXPR_SVAL ) )
+ {
+ switch( cond->u.expr.op )
+ {
+ case OP_EQ:
+ case OP_GT:
+ case OP_LT:
+ break;
+ default:
+ *valid = FALSE;
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /* FIXME: check we're comparing a string to a column */
+
+ cond->type = EXPR_STRCMP;
+ }
+
+ break;
+ case EXPR_IVAL:
+ *valid = 1;
+ cond->type = EXPR_UVAL;
+ cond->u.uval = cond->u.ival + (1<<15);
+ break;
+ case EXPR_WILDCARD:
+ *valid = 1;
+ break;
+ case EXPR_SVAL:
+ *valid = 1;
+ break;
+ default:
+ ERR("Invalid expression type\n");
+ *valid = 0;
+ break;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+UINT WHERE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table,
+ struct expr *cond )
+{
+ MSIWHEREVIEW *wv = NULL;
+ UINT count = 0, r, valid = 0;
+
+ TRACE("%p\n", wv );
+
+ r = table->ops->get_dimensions( table, NULL, &count );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("can't get table dimensions\n");
+ return r;
+ }
+
+ if( cond )
+ {
+ r = WHERE_VerifyCondition( db, table, cond, &valid );
+ if( r != ERROR_SUCCESS )
+ return r;
+ if( !valid )
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ wv = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof *wv );
+ if( !wv )
+ return ERROR_FUNCTION_FAILED;
+
+ /* fill the structure */
+ wv->view.ops = &where_ops;
+ msiobj_addref( &db->hdr );
+ wv->db = db;
+ wv->table = table;
+ wv->row_count = 0;
+ wv->reorder = NULL;
+ wv->cond = cond;
+ *view = (MSIVIEW*) wv;
+
+ return ERROR_SUCCESS;
+}
reactos/lib/msi
diff -N winehq2ros.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ winehq2ros.patch 13 Dec 2004 16:18:26 -0000 1.3.2.1
@@ -0,0 +1,99 @@
+Index: action.c
+===================================================================
+RCS file: /home/wine/wine/dlls/msi/action.c,v
+retrieving revision 1.40
+diff -u -r1.40 action.c
+--- action.c 3 Nov 2004 22:16:53 -0000 1.40
++++ action.c 7 Dec 2004 22:53:54 -0000
+@@ -28,7 +28,7 @@
+
+ #include <stdarg.h>
+ #include <stdio.h>
+-
++#include <fcntl.h>
+ #define COBJMACROS
+
+ #include "windef.h"
+@@ -39,7 +39,7 @@
+ #include "fdi.h"
+ #include "msi.h"
+ #include "msiquery.h"
+-#include "msvcrt/fcntl.h"
++//#include "msvcrt/fcntl.h"
+ #include "objbase.h"
+ #include "objidl.h"
+ #include "msipriv.h"
+@@ -2263,7 +2263,7 @@
+ version = HeapAlloc(GetProcessHeap(),0,versize);
+ GetFileVersionInfoW(file->TargetPath, 0, versize, version);
+
+- VerQueryValueW(version, name, (LPVOID*)&lpVer, &sz);
++ VerQueryValueW(version, (LPWSTR) name, (LPVOID*)&lpVer, &sz);
+
+ sprintfW(filever,name_fmt,
+ HIWORD(lpVer->dwFileVersionMS),
+Index: msi.c
+===================================================================
+RCS file: /home/wine/wine/dlls/msi/msi.c,v
+retrieving revision 1.42
+diff -u -r1.42 msi.c
+--- msi.c 7 Oct 2004 03:06:50 -0000 1.42
++++ msi.c 7 Dec 2004 22:53:55 -0000
+@@ -40,6 +40,9 @@
+
+ #include "initguid.h"
+
++UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf, DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf);
++
++
+ WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+ /*
+@@ -1392,7 +1395,7 @@
+ lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
+ lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
+
+- dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
++ dwVerLen = GetFileVersionInfoSizeW( (LPWSTR) szFilePath, NULL);
+ if(!dwVerLen)
+ return GetLastError();
+
+@@ -1402,12 +1405,12 @@
+ goto end;
+ }
+
+- if(!GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer)) {
++ if(!GetFileVersionInfoW((LPWSTR) szFilePath, 0, dwVerLen, lpVer)) {
+ ret = GetLastError();
+ goto end;
+ }
+ if(lpVersionBuf && pcchVersionBuf && *pcchVersionBuf) {
+- if(VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) && puLen > 0) {
++ if(VerQueryValueW(lpVer, (LPWSTR) szVersionResource, (LPVOID*)&ffi, &puLen) && puLen > 0) {
+ wsprintfW(tmp, szVersionFormat, HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
+ lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
+ *pcchVersionBuf = strlenW(lpVersionBuf);
+Index: suminfo.c
+===================================================================
+RCS file: /home/wine/wine/dlls/msi/suminfo.c,v
+retrieving revision 1.9
+diff -u -r1.9 suminfo.c
+--- suminfo.c 7 Oct 2004 03:06:50 -0000 1.9
++++ suminfo.c 7 Dec 2004 22:53:55 -0000
+@@ -23,6 +23,8 @@
+ #define COBJMACROS
+ #define NONAMELESSUNION
+
++#define PRSPEC_PROPID (1)
++
+ #include "windef.h"
+ #include "winbase.h"
+ #include "winreg.h"
+@@ -116,6 +118,7 @@
+ ERR("storage = %p propertysetstorage = %p\n", db->storage, psstg);
+
+ grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
++
+ r = IPropertySetStorage_Open( psstg, &FMTID_SummaryInformation, grfMode, &ps );
+ if( FAILED( r ) )
+ {
reactos/lib/msvcrt/tests
diff -N .cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ .cvsignore 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,6 @@
+*.d
+*.o
+*.exe
+*.a
+*.map
+*.sym
\ No newline at end of file
reactos/lib/msvcrt/tests
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 13 Dec 2004 16:18:27 -0000 1.2.2.1
@@ -0,0 +1,34 @@
+# $Id: Makefile,v 1.2.2.1 2004/12/13 16:18:27 hyperion Exp $
+
+PATH_TO_TOP = ../../..
+
+TARGET_NORC = yes
+
+TARGET_TYPE = program
+
+TARGET_APPTYPE = console
+
+# require os code to explicitly request A/W version of structs/functions
+TARGET_CFLAGS += -D_DISABLE_TIDENTS -D__USE_W32API -D_WIN32_IE=0x0600 \
+ -D_WIN32_WINNT=0x0501 -D__REACTOS__
+
+TARGET_NAME = msvcrt_test
+
+TARGET_SDKLIBS = ntdll.a wine.a
+
+TARGET_OBJECTS = \
+ testlist.o \
+ cpp.o \
+ environ.o \
+ file.o \
+ heap.o \
+ printf.o \
+ scanf.o \
+ string.o \
+ time.o
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
+
+# EOF
\ No newline at end of file
reactos/lib/msvcrt/tests
diff -N Makefile.in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.in 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,21 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+TESTDLL = msvcrt.dll
+IMPORTS = msvcrt
+EXTRAINCL = -I$(TOPSRCDIR)/include/msvcrt -I$(SRCDIR)/..
+
+CTESTS = \
+ cpp.c \
+ environ.c \
+ file.c \
+ heap.c \
+ printf.c \
+ scanf.c \
+ string.c \
+ time.c
+
+@MAKE_TEST_RULES@
+
+### Dependencies:
reactos/lib/msvcrt/tests
diff -N cpp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ cpp.c 13 Dec 2004 16:18:27 -0000 1.2.2.1
@@ -0,0 +1,831 @@
+/* Unit test suite for msvcrt C++ objects
+ *
+ * Copyright 2003 Jon Griffiths
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * NOTES
+ * This tests is only valid for ix86 platforms, on others it's a no-op.
+ * Some tests cannot be checked with ok(), for example the dtors. We simply
+ * call them to ensure we don't crash ;-)
+ *
+ * If we build this test with VC++ in debug mode, we will fail in _chkstk()
+ * or at program exit malloc() checking if these methods haven't been
+ * implemented correctly (they have).
+ *
+ * Tested with a range of native msvcrt's from v4 -> v7.
+ */
+#include "wine/test.h"
+#include "winbase.h"
+#include "winnt.h"
+
+#ifndef __i386__
+/* Skip these tests for non x86 platforms */
+START_TEST(cpp)
+{
+}
+#else
+
+typedef struct __exception
+{
+ void *vtable;
+ char *name;
+ int do_free;
+} exception;
+
+typedef struct __type_info
+{
+ void *vtable;
+ char *name;
+ char mangled[16];
+} type_info;
+
+/* Function pointers. We need to use these to call these funcs as __thiscall */
+static HMODULE hMsvcrt;
+
+static void* (*poperator_new)(unsigned int);
+static void (*poperator_delete)(void*);
+static void* (*pmalloc)(unsigned int);
+static void (*pfree)(void*);
+
+/* exception */
+static void (WINAPI *pexception_ctor)(exception*,LPCSTR*);
+static void (WINAPI *pexception_copy_ctor)(exception*,exception*);
+static void (WINAPI *pexception_default_ctor)(exception*);
+static void (WINAPI *pexception_dtor)(exception*);
+static exception* (WINAPI *pexception_opequals)(exception*,exception*);
+static char* (WINAPI *pexception_what)(exception*);
+static void* (WINAPI *pexception_vtable)(exception*);
+static void (WINAPI *pexception_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *pexception_scalar_dtor)(exception*,unsigned int);
+
+/* bad_typeid */
+static void (WINAPI *pbad_typeid_ctor)(exception*,LPCSTR);
+static void (WINAPI *pbad_typeid_ctor_closure)(exception*);
+static void (WINAPI *pbad_typeid_copy_ctor)(exception*,exception*);
+static void (WINAPI *pbad_typeid_dtor)(exception*);
+static exception* (WINAPI *pbad_typeid_opequals)(exception*,exception*);
+static char* (WINAPI *pbad_typeid_what)(exception*);
+static void* (WINAPI *pbad_typeid_vtable)(exception*);
+static void (WINAPI *pbad_typeid_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *pbad_typeid_scalar_dtor)(exception*,unsigned int);
+
+/* bad_cast */
+static void (WINAPI *pbad_cast_ctor)(exception*,LPCSTR*);
+static void (WINAPI *pbad_cast_ctor2)(exception*,LPCSTR);
+static void (WINAPI *pbad_cast_ctor_closure)(exception*);
+static void (WINAPI *pbad_cast_copy_ctor)(exception*,exception*);
+static void (WINAPI *pbad_cast_dtor)(exception*);
+static exception* (WINAPI *pbad_cast_opequals)(exception*,exception*);
+static char* (WINAPI *pbad_cast_what)(exception*);
+static void* (WINAPI *pbad_cast_vtable)(exception*);
+static void (WINAPI *pbad_cast_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *pbad_cast_scalar_dtor)(exception*,unsigned int);
+
+/* __non_rtti_object */
+static void (WINAPI *p__non_rtti_object_ctor)(exception*,LPCSTR);
+static void (WINAPI *p__non_rtti_object_copy_ctor)(exception*,exception*);
+static void (WINAPI *p__non_rtti_object_dtor)(exception*);
+static exception* (WINAPI *p__non_rtti_object_opequals)(exception*,exception*);
+static char* (WINAPI *p__non_rtti_object_what)(exception*);
+static void* (WINAPI *p__non_rtti_object_vtable)(exception*);
+static void (WINAPI *p__non_rtti_object_vector_dtor)(exception*,unsigned int);
+static void (WINAPI *p__non_rtti_object_scalar_dtor)(exception*,unsigned int);
+
+/* type_info */
+static void (WINAPI *ptype_info_dtor)(type_info*);
+static char* (WINAPI *ptype_info_raw_name)(type_info*);
+static char* (WINAPI *ptype_info_name)(type_info*);
+static int (WINAPI *ptype_info_before)(type_info*,type_info*);
+static int (WINAPI *ptype_info_opequals_equals)(type_info*,type_info*);
+static int (WINAPI *ptype_info_opnot_equals)(type_info*,type_info*);
+
+/* RTTI */
+static type_info* (*p__RTtypeid)(void*);
+static void* (*p__RTCastToVoid)(void*);
+static void* (*p__RTDynamicCast)(void*,int,void*,void*,int);
+
+/* _very_ early native versions have serious RTTI bugs, so we check */
+static void* bAncientVersion;
+
+/* Emulate a __thiscall */
+#ifdef _MSC_VER
+inline static void* do_call_func1(void *func, void *_this)
+{
+ volatile void* retval = 0;
+ __asm
+ {
+ push ecx
+ mov ecx, _this
+ call func
+ mov retval, eax
+ pop ecx
+ }
+ return (void*)retval;
+}
+
+inline static void* do_call_func2(void *func, void *_this, void* arg)
+{
+ volatile void* retval = 0;
+ __asm
+ {
+ push ecx
+ push arg
+ mov ecx, _this
+ call func
+ mov retval, eax
+ pop ecx
+ }
+ return (void*)retval;
+}
+#else
+static void* do_call_func1(void *func, void *_this)
+{
+ void* ret;
+ __asm__ __volatile__ ("call *%1"
+ : "=a" (ret)
+ : "g" (func), "c" (_this)
+ : "memory" );
+ return ret;
+}
+static void* do_call_func2(void *func, void *_this, void* arg)
+{
+ void* ret;
+ __asm__ __volatile__ ("pushl %2\n\tcall *%1"
+ : "=a" (ret)
+ : "r" (func), "g" (arg), "c" (_this)
+ : "memory" );
+ return ret;
+}
+#endif
+
+#define call_func1(x,y) do_call_func1((void*)x,(void*)y)
+#define call_func2(x,y,z) do_call_func2((void*)x,(void*)y,(void*)z)
+
+/* Some exports are only available in later versions */
+#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
+#define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
+
+static void InitFunctionPtrs()
+{
+ hMsvcrt = LoadLibraryA("msvcrt.dll");
+ ok(hMsvcrt != 0, "LoadLibraryA failed\n");
+ if (hMsvcrt)
+ {
+ SETNOFAIL(poperator_new, "??_U@YAPAXI@Z");
+ SETNOFAIL(poperator_delete, "??_V@YAXPAX@Z");
+ SET(pmalloc, "malloc");
+ SET(pfree, "free");
+
+ if (!poperator_new)
+ poperator_new = pmalloc;
+ if (!poperator_delete)
+ poperator_delete = pfree;
+
+ SET(pexception_ctor, "??0exception@@QAE@ABQBD@Z");
+ SET(pexception_copy_ctor, "??0exception@@QAE@ABV0@@Z");
+ SET(pexception_default_ctor, "??0exception@@QAE@XZ");
+ SET(pexception_dtor, "??1exception@@UAE@XZ");
+ SET(pexception_opequals, "??4exception@@QAEAAV0@ABV0@@Z");
+ SET(pexception_what, "?what@exception@@UBEPBDXZ");
+ SET(pexception_vtable, "??_7exception@@6B@");
+ SET(pexception_vector_dtor, "??_Eexception@@UAEPAXI@Z");
+ SET(pexception_scalar_dtor, "??_Gexception@@UAEPAXI@Z");
+
+ SET(pbad_typeid_ctor, "??0bad_typeid@@QAE@PBD@Z");
+ SETNOFAIL(pbad_typeid_ctor_closure, "??_Fbad_typeid@@QAEXXZ");
+ SET(pbad_typeid_copy_ctor, "??0bad_typeid@@QAE@ABV0@@Z");
+ SET(pbad_typeid_dtor, "??1bad_typeid@@UAE@XZ");
+ SET(pbad_typeid_opequals, "??4bad_typeid@@QAEAAV0@ABV0@@Z");
+ SET(pbad_typeid_what, "?what@exception@@UBEPBDXZ");
+ SET(pbad_typeid_vtable, "??_7bad_typeid@@6B@");
+ SET(pbad_typeid_vector_dtor, "??_Ebad_typeid@@UAEPAXI@Z");
+ SET(pbad_typeid_scalar_dtor, "??_Gbad_typeid@@UAEPAXI@Z");
+
+ SETNOFAIL(pbad_cast_ctor, "??0bad_cast@@QAE@ABQBD@Z");
+ if (!pbad_cast_ctor)
+ SET(pbad_cast_ctor, "??0bad_cast@@AAE@PBQBD@Z");
+ SETNOFAIL(pbad_cast_ctor2, "??0bad_cast@@QAE@PBD@Z");
+ SETNOFAIL(pbad_cast_ctor_closure, "??_Fbad_cast@@QAEXXZ");
+ SET(pbad_cast_copy_ctor, "??0bad_cast@@QAE@ABV0@@Z");
+ SET(pbad_cast_dtor, "??1bad_cast@@UAE@XZ");
+ SET(pbad_cast_opequals, "??4bad_cast@@QAEAAV0@ABV0@@Z");
+ SET(pbad_cast_what, "?what@exception@@UBEPBDXZ");
+ SET(pbad_cast_vtable, "??_7bad_cast@@6B@");
+ SET(pbad_cast_vector_dtor, "??_Ebad_cast@@UAEPAXI@Z");
+ SET(pbad_cast_scalar_dtor, "??_Gbad_cast@@UAEPAXI@Z");
+
+ SET(p__non_rtti_object_ctor, "??0__non_rtti_object@@QAE@PBD@Z");
+ SET(p__non_rtti_object_copy_ctor, "??0__non_rtti_object@@QAE@ABV0@@Z");
+ SET(p__non_rtti_object_dtor, "??1__non_rtti_object@@UAE@XZ");
+ SET(p__non_rtti_object_opequals, "??4__non_rtti_object@@QAEAAV0@ABV0@@Z");
+ SET(p__non_rtti_object_what, "?what@exception@@UBEPBDXZ");
+ SET(p__non_rtti_object_vtable, "??_7__non_rtti_object@@6B@");
+ SET(p__non_rtti_object_vector_dtor, "??_E__non_rtti_object@@UAEPAXI@Z");
+ SET(p__non_rtti_object_scalar_dtor, "??_G__non_rtti_object@@UAEPAXI@Z");
+
+ SET(ptype_info_dtor, "??1type_info@@UAE@XZ");
+ SET(ptype_info_raw_name, "?raw_name@type_info@@QBEPBDXZ");
+#ifndef __REACTOS__
+ SET(ptype_info_name, "?name@type_info@@QBEPBDXZ");
+#endif
+ SET(ptype_info_before, "?before@type_info@@QBEHABV1@@Z");
+ SET(ptype_info_opequals_equals, "??8type_info@@QBEHABV0@@Z");
+ SET(ptype_info_opnot_equals, "??9type_info@@QBEHABV0@@Z");
+
+ SET(p__RTtypeid, "__RTtypeid");
+ SET(p__RTCastToVoid, "__RTCastToVoid");
+ SET(p__RTDynamicCast, "__RTDynamicCast");
+
+ /* Extremely early versions export logic_error, and crash in RTTI */
+ SETNOFAIL(bAncientVersion, "??0logic_error@@QAE@ABQBD@Z");
+ }
+}
+
+static void test_exception(void)
+{
+ static const char* e_name = "An exception name";
+ char* name;
+ exception e, e2, e3, *pe;
+
+ if (!poperator_new || !poperator_delete ||
+ !pexception_ctor || !pexception_copy_ctor || !pexception_default_ctor ||
+ !pexception_dtor || !pexception_opequals || !pexception_what ||
+ !pexception_vtable || !pexception_vector_dtor || !pexception_scalar_dtor)
+ return;
+
+ /* 'const char*&' ctor */
+ memset(&e, 0, sizeof(e));
+ call_func2(pexception_ctor, &e, &e_name);
+ ok(e.vtable != NULL, "Null exception vtable for e\n");
+ ok(e.name && e.name != e_name && !strcmp(e.name, "An exception name"), "Bad name '%s' for e\n", e.name);
+ ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+ /* Copy ctor */
+ memset(&e2, 0, sizeof(e2));
+ call_func2(pexception_copy_ctor, &e2, &e);
+ ok(e2.vtable != NULL, "Null exception vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "An exception name"), "Bad exception name for e2\n");
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+
+ /* Default ctor */
+ memset(&e3, 1, sizeof(e3));
+ call_func1(pexception_default_ctor, &e3);
+ ok(e3.vtable != NULL, "Null exception vtable for e3\n");
+ ok(e3.name == NULL, "Bad exception name for e3\n");
+ ok(e3.do_free == 0, "do_free set to %d for e3\n", e3.do_free);
+
+ ok(e.vtable == e2.vtable && e.vtable == e3.vtable, "exception vtables differ!\n");
+
+ /* Test calling the dtors */
+ call_func1(pexception_dtor, &e2);
+ call_func1(pexception_dtor, &e3);
+
+ /* Operator equals */
+ memset(&e2, 0, sizeof(e2));
+ pe = call_func2(pexception_opequals, &e2, &e);
+ ok(e2.vtable != NULL, "Null exception vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "An exception name"), "Bad exception name for e2\n");
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+ ok(pe == &e2, "opequals didn't return e2\n");
+
+ /* what() */
+ name = call_func1(pexception_what, &e2);
+ ok(e2.name == name, "Bad exception name from e2::what()\n");
+
+ /* vtable ptr */
+ ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+ call_func1(pexception_dtor, &e2);
+
+ /* new() */
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ call_func2(pexception_ctor, pe, &e_name);
+ /* scalar dtor */
+ call_func2(pexception_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+ pe->name = NULL;
+ pe->do_free = 0;
+ call_func2(pexception_scalar_dtor, pe, 1); /* Should delete pe */
+ }
+
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, single element */
+ call_func2(pexception_ctor, pe, &e_name);
+ call_func2(pexception_vector_dtor, pe, 1); /* Should delete pe as single element*/
+ }
+
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, multiple elements */
+ char name[] = "a constant";
+ *((int*)pe) = 3;
+ pe = (exception*)((int*)pe + 1);
+ call_func2(pexception_ctor, &pe[0], &e_name);
+ call_func2(pexception_ctor, &pe[1], &e_name);
+ call_func2(pexception_ctor, &pe[2], &e_name);
+ pe[3].name = name;
+ pe[3].do_free = 1; /* Crash if we try to free this */
+ call_func2(pexception_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+ }
+
+ /* test our exported vtable is kosher */
+ pe = (void*)pexception_vtable; /* Use the exception struct to get vtable ptrs */
+ pexception_vector_dtor = (void*)pe->vtable;
+ pexception_what = (void*)pe->name;
+
+ name = call_func1(pexception_what, &e);
+ ok(e.name == name, "Bad exception name from vtable e::what()\n");
+
+ if (p__RTtypeid && !bAncientVersion)
+ {
+ /* Check the rtti */
+ type_info *ti = p__RTtypeid(&e);
+ ok (ti && ti->mangled &&
+ !strcmp(ti->mangled, ".?AVexception@@"), "bad rtti for e\n");
+
+ if (ti)
+ {
+ /* Check the returned type_info has rtti too */
+ type_info *ti2 = p__RTtypeid(ti);
+ ok (ti2 != NULL && !strcmp(ti2->mangled, ".?AVtype_info@@"), "bad rtti for e's type_info\n");
+ }
+ }
+
+ call_func2(pexception_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+/* This test is basically a cut 'n' paste of the exception test. but it verifies that
+ * bad_typeid works the exact same way... */
+static void test_bad_typeid(void)
+{
+ static const char* e_name = "A bad_typeid name";
+ char* name;
+ exception e, e2, e3, *pe;
+
+ if (!poperator_new || !poperator_delete ||
+ !pbad_typeid_ctor || !pbad_typeid_copy_ctor ||
+ !pbad_typeid_dtor || !pbad_typeid_opequals || !pbad_typeid_what ||
+ !pbad_typeid_vtable || !pbad_typeid_vector_dtor || !pbad_typeid_scalar_dtor)
+ return;
+
+ /* 'const char*' ctor */
+ memset(&e, 0, sizeof(e));
+ call_func2(pbad_typeid_ctor, &e, e_name);
+ ok(e.vtable != NULL, "Null bad_typeid vtable for e\n");
+ ok(e.name && e.name != e_name && !strcmp(e.name, "A bad_typeid name"), "Bad name '%s' for e\n", e.name);
+ ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+ /* Copy ctor */
+ memset(&e2, 0, sizeof(e2));
+ call_func2(pbad_typeid_copy_ctor, &e2, &e);
+ ok(e2.vtable != NULL, "Null bad_typeid vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_typeid name"), "Bad name '%s' for e2\n", e2.name);
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+
+ /* Ctor closure */
+ if (pbad_typeid_ctor_closure)
+ {
+ memset(&e3, 1, sizeof(e3));
+ call_func1(pbad_typeid_ctor_closure, &e3);
+ ok(e3.vtable != NULL, "Null bad_typeid vtable for e3\n");
+ ok(e3.name && !strcmp(e3.name, "bad typeid"), "Bad bad_typeid name for e3\n");
+ ok(e3.do_free == 1, "do_free set to %d for e3\n", e3.do_free);
+ ok(e.vtable == e3.vtable, "bad_typeid closure vtables differ!\n");
+ call_func1(pbad_typeid_dtor, &e3);
+ }
+ ok(e.vtable == e2.vtable, "bad_typeid vtables differ!\n");
+
+ /* Test calling the dtors */
+ call_func1(pbad_typeid_dtor, &e2);
+
+ /* Operator equals */
+ memset(&e2, 1, sizeof(e2));
+ pe = call_func2(pbad_typeid_opequals, &e2, &e);
+ ok(e2.vtable != NULL, "Null bad_typeid vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_typeid name"), "Bad bad_typeid name for e2\n");
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+ ok(pe == &e2, "opequals didn't return e2\n");
+
+ /* what() */
+ name = call_func1(pbad_typeid_what, &e2);
+ ok(e2.name == name, "Bad bad_typeid name from e2::what()\n");
+
+ /* vtable ptr */
+ ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+ call_func1(pbad_typeid_dtor, &e2);
+
+ /* new() */
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ call_func2(pbad_typeid_ctor, pe, e_name);
+ /* scalar dtor */
+ call_func2(pbad_typeid_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+ pe->name = NULL;
+ pe->do_free = 0;
+ call_func2(pbad_typeid_scalar_dtor, pe, 1); /* Should delete pe */
+ }
+
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, single element */
+ call_func2(pbad_typeid_ctor, pe, e_name);
+ call_func2(pbad_typeid_vector_dtor, pe, 1); /* Should delete pe as single element*/
+ }
+
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, multiple elements */
+ *((int*)pe) = 3;
+ pe = (exception*)((int*)pe + 1);
+ call_func2(pbad_typeid_ctor, &pe[0], e_name);
+ call_func2(pbad_typeid_ctor, &pe[1], e_name);
+ call_func2(pbad_typeid_ctor, &pe[2], e_name);
+ pe[3].name = 0;
+ pe[3].do_free = 1; /* Crash if we try to free this element */
+ call_func2(pbad_typeid_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+ }
+
+ /* test our exported vtable is kosher */
+ pe = (void*)pbad_typeid_vtable; /* Use the exception struct to get vtable ptrs */
+ pbad_typeid_vector_dtor = (void*)pe->vtable;
+ pbad_typeid_what = (void*)pe->name;
+
+ name = call_func1(pbad_typeid_what, &e);
+ ok(e.name == name, "Bad bad_typeid name from vtable e::what()\n");
+
+ if (p__RTtypeid && !bAncientVersion)
+ {
+ /* Check the rtti */
+ type_info *ti = p__RTtypeid(&e);
+ ok (ti != NULL && !strcmp(ti->mangled, ".?AVbad_typeid@@"), "bad rtti for e (%s)\n",
+ !ti ? "null" : ti->mangled);
+ }
+
+ call_func2(pbad_typeid_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+
+/* Ditto for this test... */
+static void test_bad_cast(void)
+{
+ static const char* e_name = "A bad_cast name";
+ char* name;
+ exception e, e2, e3, *pe;
+
+ if (!poperator_new || !poperator_delete ||
+ !pbad_cast_ctor || !pbad_cast_copy_ctor ||
+ !pbad_cast_dtor || !pbad_cast_opequals || !pbad_cast_what ||
+ !pbad_cast_vtable || !pbad_cast_vector_dtor || !pbad_cast_scalar_dtor)
+ return;
+
+ if (pbad_cast_ctor2)
+ {
+ /* 'const char*' ctor */
+ memset(&e, 0, sizeof(e));
+ call_func2(pbad_cast_ctor2, &e, e_name);
+ ok(e.vtable != NULL, "Null bad_cast vtable for e\n");
+ ok(e.name && e.name != e_name && !strcmp(e.name, "A bad_cast name"), "Bad name '%s' for e\n", e.name);
+ ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+ call_func1(pbad_cast_dtor, &e);
+ }
+
+ /* 'const char*&' ctor */
+ memset(&e, 0, sizeof(e));
+ call_func2(pbad_cast_ctor, &e, &e_name);
+ ok(e.vtable != NULL, "Null bad_cast vtable for e\n");
+ ok(e.name && e.name != e_name && !strcmp(e.name, "A bad_cast name"), "Bad name '%s' for e\n", e.name);
+ ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+ /* Copy ctor */
+ memset(&e2, 0, sizeof(e2));
+ call_func2(pbad_cast_copy_ctor, &e2, &e);
+ ok(e2.vtable != NULL, "Null bad_cast vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_cast name"), "Bad name '%s' for e2\n", e2.name);
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+
+ /* Ctor closure */
+ if (pbad_cast_ctor_closure)
+ {
+ memset(&e3, 1, sizeof(e3));
+ call_func1(pbad_cast_ctor_closure, &e3);
+ ok(e3.vtable != NULL, "Null bad_cast vtable for e3\n");
+ ok(e3.name && !strcmp(e3.name, "bad cast"), "Bad bad_cast name for e3\n");
+ ok(e3.do_free == 1, "do_free set to %d for e3\n", e3.do_free);
+ ok(e.vtable == e3.vtable, "bad_cast closure vtables differ!\n");
+ call_func1(pbad_cast_dtor, &e3);
+ }
+ ok(e.vtable == e2.vtable, "bad_cast vtables differ!\n");
+
+ /* Test calling the dtors */
+ call_func1(pbad_cast_dtor, &e2);
+
+ /* Operator equals */
+ memset(&e2, 1, sizeof(e2));
+ pe = call_func2(pbad_cast_opequals, &e2, &e);
+ ok(e2.vtable != NULL, "Null bad_cast vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A bad_cast name"), "Bad bad_cast name for e2\n");
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+ ok(pe == &e2, "opequals didn't return e2\n");
+
+ /* what() */
+ name = call_func1(pbad_cast_what, &e2);
+ ok(e2.name == name, "Bad bad_cast name from e2::what()\n");
+
+ /* vtable ptr */
+ ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+ call_func1(pbad_cast_dtor, &e2);
+
+ /* new() */
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ call_func2(pbad_cast_ctor, pe, &e_name);
+ /* scalar dtor */
+ call_func2(pbad_cast_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+ pe->name = NULL;
+ pe->do_free = 0;
+ call_func2(pbad_cast_scalar_dtor, pe, 1); /* Should delete pe */
+ }
+
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, single element */
+ call_func2(pbad_cast_ctor, pe, &e_name);
+ call_func2(pbad_cast_vector_dtor, pe, 1); /* Should delete pe as single element*/
+ }
+
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, multiple elements */
+ *((int*)pe) = 3;
+ pe = (exception*)((int*)pe + 1);
+ call_func2(pbad_cast_ctor, &pe[0], &e_name);
+ call_func2(pbad_cast_ctor, &pe[1], &e_name);
+ call_func2(pbad_cast_ctor, &pe[2], &e_name);
+ pe[3].name = 0;
+ pe[3].do_free = 1; /* Crash if we try to free this element */
+ call_func2(pbad_cast_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+ }
+
+ /* test our exported vtable is kosher */
+ pe = (void*)pbad_cast_vtable; /* Use the exception struct to get vtable ptrs */
+ pbad_cast_vector_dtor = (void*)pe->vtable;
+ pbad_cast_what = (void*)pe->name;
+
+ name = call_func1(pbad_cast_what, &e);
+ ok(e.name == name, "Bad bad_cast name from vtable e::what()\n");
+
+ if (p__RTtypeid && !bAncientVersion)
+ {
+ /* Check the rtti */
+ type_info *ti = p__RTtypeid(&e);
+ ok (ti != NULL && !strcmp(ti->mangled, ".?AVbad_cast@@"), "bad rtti for e\n");
+ }
+ call_func2(pbad_cast_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+/* ... and this one */
+static void test___non_rtti_object(void)
+{
+ static const char* e_name = "A __non_rtti_object name";
+ char* name;
+ exception e, e2, *pe;
+
+ if (!poperator_new || !poperator_delete ||
+ !p__non_rtti_object_ctor || !p__non_rtti_object_copy_ctor ||
+ !p__non_rtti_object_dtor || !p__non_rtti_object_opequals || !p__non_rtti_object_what ||
+ !p__non_rtti_object_vtable || !p__non_rtti_object_vector_dtor || !p__non_rtti_object_scalar_dtor)
+ return;
+
+ /* 'const char*' ctor */
+ memset(&e, 0, sizeof(e));
+ call_func2(p__non_rtti_object_ctor, &e, e_name);
+ ok(e.vtable != NULL, "Null __non_rtti_object vtable for e\n");
+ ok(e.name && e.name != e_name && !strcmp(e.name, "A __non_rtti_object name"), "Bad name '%s' for e\n", e.name);
+ ok(e.do_free == 1, "do_free set to %d for e\n", e.do_free);
+
+ /* Copy ctor */
+ memset(&e2, 0, sizeof(e2));
+ call_func2(p__non_rtti_object_copy_ctor, &e2, &e);
+ ok(e2.vtable != NULL, "Null __non_rtti_object vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A __non_rtti_object name"), "Bad name '%s' for e2\n", e2.name);
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+ ok(e.vtable == e2.vtable, "__non_rtti_object vtables differ!\n");
+
+ /* Test calling the dtors */
+ call_func1(p__non_rtti_object_dtor, &e2);
+
+ /* Operator equals */
+ memset(&e2, 1, sizeof(e2));
+ pe = call_func2(p__non_rtti_object_opequals, &e2, &e);
+ ok(e2.vtable != NULL, "Null __non_rtti_object vtable for e2\n");
+ ok(e2.name && e2.name != e.name && !strcmp(e2.name, "A __non_rtti_object name"), "Bad __non_rtti_object name for e2\n");
+ ok(e2.do_free == 1, "do_free set to %d for e2\n", e2.do_free);
+ ok(pe == &e2, "opequals didn't return e2\n");
+
+ /* what() */
+ name = call_func1(p__non_rtti_object_what, &e2);
+ ok(e2.name == name, "Bad __non_rtti_object name from e2::what()\n");
+
+ /* vtable ptr */
+ ok(e2.vtable == pexception_vtable, "Bad vtable for e2\n");
+ call_func1(p__non_rtti_object_dtor, &e2);
+
+ /* new() */
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ call_func2(p__non_rtti_object_ctor, pe, e_name);
+ /* scalar dtor */
+ call_func2(p__non_rtti_object_scalar_dtor, pe, 0); /* Shouldn't delete pe */
+ pe->name = NULL;
+ pe->do_free = 0;
+ call_func2(p__non_rtti_object_scalar_dtor, pe, 1); /* Should delete pe */
+ }
+
+ pe = poperator_new(sizeof(exception));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, single element */
+ call_func2(p__non_rtti_object_ctor, pe, e_name);
+ call_func2(p__non_rtti_object_vector_dtor, pe, 1); /* Should delete pe as single element*/
+ }
+
+ pe = poperator_new(sizeof(exception) * 4 + sizeof(int));
+ ok(pe != NULL, "new() failed\n");
+ if (pe)
+ {
+ /* vector dtor, multiple elements */
+ *((int*)pe) = 3;
+ pe = (exception*)((int*)pe + 1);
+ call_func2(p__non_rtti_object_ctor, &pe[0], e_name);
+ call_func2(p__non_rtti_object_ctor, &pe[1], e_name);
+ call_func2(p__non_rtti_object_ctor, &pe[2], e_name);
+ pe[3].name = 0;
+ pe[3].do_free = 1; /* Crash if we try to free this element */
+ call_func2(p__non_rtti_object_vector_dtor, pe, 3); /* Should delete all 3 and then pe block */
+ }
+
+ /* test our exported vtable is kosher */
+ pe = (void*)p__non_rtti_object_vtable; /* Use the exception struct to get vtable ptrs */
+ p__non_rtti_object_vector_dtor = (void*)pe->vtable;
+ p__non_rtti_object_what = (void*)pe->name;
+
+ name = call_func1(p__non_rtti_object_what, &e);
+ ok(e.name == name, "Bad __non_rtti_object name from vtable e::what()\n");
+
+ if (p__RTtypeid && !bAncientVersion)
+ {
+ /* Check the rtti */
+ type_info *ti = p__RTtypeid(&e);
+ ok (ti != NULL && !strcmp(ti->mangled, ".?AV__non_rtti_object@@"), "bad rtti for e\n");
+ }
+ call_func2(p__non_rtti_object_vector_dtor, &e, 0); /* Should delete e.name, but not e */
+}
+
+
+static void test_type_info(void)
+{
+ static type_info t1 = { NULL, NULL,{'.','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
+ static type_info t1_1 = { NULL, NULL,{'?','?','A','V','t','e','s','t','1','@','@',0,0,0,0,0 } };
+ static type_info t2 = { NULL, NULL, {'.','?','A','V','t','e','s','t','2','@','@',0,0,0,0,0 } };
+ char* name;
+ int res;
+
+ if (!pmalloc || !pfree || !ptype_info_dtor || !ptype_info_raw_name ||
+ !ptype_info_name || !ptype_info_before ||
+ !ptype_info_opequals_equals || !ptype_info_opnot_equals)
+ return;
+
+ /* Test calling the dtors */
+ call_func1(ptype_info_dtor, &t1); /* No effect, since name is NULL */
+ t1.name = pmalloc(64);
+ strcpy(t1.name, "foo");
+ call_func1(ptype_info_dtor, &t1); /* Frees t1.name using 'free' */
+
+ /* raw_name */
+ t1.name = NULL;
+ name = call_func1(ptype_info_raw_name, &t1);
+
+ /* FIXME: This fails on native; it shouldn't though - native bug?
+ * ok(name && !strcmp(name, t1.mangled), "bad raw_name '%s' for t1 (expected '%s')\n", name, t1.mangled);
+ */
+ ok(t1.name == NULL, "raw_name() set name for t1\n");
+
+ /* name */
+ t1.name = NULL;
+ name = call_func1(ptype_info_name, &t1);
+ ok(name && t1.name && !strcmp(name, t1.name), "bad name '%s' for t1\n", name);
+
+ ok(t1.name && !strcmp(t1.name, "class test1"), "demangled to '%s' for t1\n", t1.name);
+ call_func1(ptype_info_dtor, &t1);
+
+ /* before */
+ t1.name = NULL;
+ res = (int)call_func2(ptype_info_before, &t1, &t1);
+ ok(res == 0, "expected 0, got %d\n", res);
+ res = (int)call_func2(ptype_info_before, &t2, &t1);
+ ok(res == 0, "expected 0, got %d\n", res);
+ res = (int)call_func2(ptype_info_before, &t1, &t2);
+ ok(res == 1, "expected 1, got %d\n", res);
+ /* Doesn't check first char */
+ res = (int)call_func2(ptype_info_before, &t1, &t1_1);
+ ok(res == 0, "expected 0, got %d\n", res);
+
+ /* opequals_equals */
+ t1.name = NULL;
+ res = (int)call_func2(ptype_info_opequals_equals, &t1, &t1);
+ ok(res == 1, "expected 1, got %d\n", res);
+ res = (int)call_func2(ptype_info_opequals_equals, &t1, &t2);
+ ok(res == 0, "expected 0, got %d\n", res);
+ res = (int)call_func2(ptype_info_opequals_equals, &t2, &t1);
+ ok(res == 0, "expected 0, got %d\n", res);
+
+ /* opnot_equals */
+ t1.name = NULL;
+ res = (int)call_func2(ptype_info_opnot_equals, &t1, &t1);
+ ok(res == 0, "expected 0, got %d\n", res);
+ res = (int)call_func2(ptype_info_opnot_equals, &t1, &t2);
+ ok(res == 1, "expected 1, got %d\n", res);
+ res = (int)call_func2(ptype_info_opnot_equals, &t2, &t1);
+ ok(res == 1, "expected 1, got %d\n", res);
+}
+
+/* Test RTTI functions */
+static void test_rtti(void)
+{
+ static const char* e_name = "name";
+ type_info *ti,*bti;
+ exception e,b;
+ void *casted;
+
+ if (bAncientVersion ||
+ !p__RTCastToVoid || !p__RTtypeid || !pexception_ctor || !pbad_typeid_ctor || !p__RTDynamicCast)
+ return;
+
+ call_func2(pexception_ctor, &e, &e_name);
+ call_func2(pbad_typeid_ctor, &b, e_name);
+
+ /* dynamic_cast to void* */
+ casted = p__RTCastToVoid(&e);
+ ok (casted == (void*)&e, "failed cast to void\n");
+
+ /* dynamic_cast up */
+ ti = p__RTtypeid(&e);
+ bti = p__RTtypeid(&b);
+
+ casted = p__RTDynamicCast(&b, 0, NULL, ti, 0);
+ ok (casted == (void*)&b, "failed cast from bad_cast to exception\n");
+
+ /* dynamic_cast down */
+ casted = p__RTDynamicCast(&e, 0, NULL, bti, 0);
+ ok (casted == NULL, "Cast succeeded\n");
+}
+
+START_TEST(cpp)
+{
+ InitFunctionPtrs();
+
+ test_exception();
+ test_bad_typeid();
+ test_bad_cast();
+ test___non_rtti_object();
+ test_type_info();
+ test_rtti();
+
+ if (hMsvcrt)
+ FreeLibrary(hMsvcrt);
+}
+#endif /* __i386__ */
reactos/lib/msvcrt/tests
diff -N environ.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ environ.c 13 Dec 2004 16:18:27 -0000 1.2.2.1
@@ -0,0 +1,38 @@
+/*
+ * Unit tests for C library environment routines
+ *
+ * Copyright 2004 Mike Hearn <mh@codeweavers.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "wine/test.h"
+#include <stdlib.h>
+
+START_TEST(environ)
+{
+#ifndef __REACTOS__
+ ok( _putenv("cat=") == 0, "_putenv failed on deletion of non-existent environment variable\n" );
+#endif
+ ok( _putenv("cat=dog") == 0, "failed setting cat=dog\n" );
+ ok( strcmp(getenv("cat"), "dog") == 0, "getenv did not return 'dog'\n" );
+ ok( _putenv("cat=") == 0, "failed deleting cat\n" );
+
+ ok( _putenv("=") == -1, "should not accept '=' as input\n" );
+#ifndef __REACTOS__
+ ok( _putenv("=dog") == -1, "should not accept '=dog' as input\n" );
+#endif
+ ok( getenv("nonexistent") == NULL, "getenv should fail with nonexistent var name\n" );
+}
reactos/lib/msvcrt/tests
diff -N file.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ file.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,331 @@
+/*
+ * Unit test suite for file functions
+ *
+ * Copyright 2002 Bill Currie
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "wine/test.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+#include <process.h>
+#include <errno.h>
+
+static void test_fdopen( void )
+{
+ static const char buffer[] = {0,1,2,3,4,5,6,7,8,9};
+ char ibuf[10];
+ int fd;
+ FILE *file;
+
+ fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
+ write (fd, buffer, sizeof (buffer));
+ close (fd);
+
+ fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
+ lseek (fd, 5, SEEK_SET);
+ file = fdopen (fd, "rb");
+ ok (fread (ibuf, 1, sizeof (buffer), file) == 5, "read wrong byte count\n");
+ ok (memcmp (ibuf, buffer + 5, 5) == 0, "read wrong bytes\n");
+ fclose (file);
+ unlink ("fdopen.tst");
+}
+
+static void test_fileops( void )
+{
+ static const char outbuffer[] = "0,1,2,3,4,5,6,7,8,9";
+ char buffer[256];
+ WCHAR wbuffer[256];
+ int fd;
+ FILE *file;
+
+ fd = open ("fdopen.tst", O_WRONLY | O_CREAT | O_BINARY, _S_IREAD |_S_IWRITE);
+ write (fd, outbuffer, sizeof (outbuffer));
+ close (fd);
+
+ fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
+ file = fdopen (fd, "rb");
+ ok(strlen(outbuffer) == (sizeof(outbuffer)-1),"strlen/sizeof error\n");
+ ok(fgets(buffer,sizeof(buffer),file) !=0,"fgets failed unexpected\n");
+ ok(fgets(buffer,sizeof(buffer),file) ==0,"fgets didn't signal EOF\n");
+ ok(feof(file) !=0,"feof doesn't signal EOF\n");
+ rewind(file);
+ ok(fgets(buffer,strlen(outbuffer),file) !=0,"fgets failed unexpected\n");
+ ok(lstrlenA(buffer) == strlen(outbuffer) -1,"fgets didn't read right size\n");
+ ok(fgets(buffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
+ ok(strlen(buffer) == 1,"fgets dropped chars\n");
+ ok(buffer[0] == outbuffer[strlen(outbuffer)-1],"fgets exchanged chars\n");
+ fclose (file);
+ fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
+ file = fdopen (fd, "rt"); /* open in TEXT mode */
+ ok(fgetws(wbuffer,sizeof(wbuffer),file) !=0,"fgetws failed unexpected\n");
+ ok(fgetws(wbuffer,sizeof(wbuffer),file) ==0,"fgetws didn't signal EOF\n");
+ ok(feof(file) !=0,"feof doesn't signal EOF\n");
+ rewind(file);
+ ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
+ ok(lstrlenW(wbuffer) == (strlen(outbuffer) -1),"fgetws didn't read right size\n");
+ ok(fgetws(wbuffer,sizeof(outbuffer),file) !=0,"fgets failed unexpected\n");
+ ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
+ fclose (file);
+ unlink ("fdopen.tst");
+}
+
+static WCHAR* AtoW( char* p )
+{
+ WCHAR* buffer;
+ DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 );
+ buffer = malloc( len * sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len );
+ return buffer;
+}
+
+static void test_fgetwc( void )
+{
+#define LLEN 512
+
+ char* tempf;
+ FILE *tempfh;
+ static const char mytext[]= "This is test_fgetwc\n";
+ WCHAR wtextW[LLEN+1];
+ WCHAR *mytextW = NULL, *aptr, *wptr;
+ BOOL diff_found = FALSE;
+ unsigned int i;
+
+ tempf=_tempnam(".","wne");
+ tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
+ fputs(mytext,tempfh);
+ fclose(tempfh);
+ tempfh = fopen(tempf,"rt");
+ fgetws(wtextW,LLEN,tempfh);
+ mytextW = AtoW ((char*)mytext);
+ aptr = mytextW;
+ wptr = wtextW;
+
+ for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
+ {
+ diff_found |= (*aptr != *wptr);
+ }
+ ok(!(diff_found), "fgetwc difference found in TEXT mode\n");
+ if(mytextW) free (mytextW);
+ fclose(tempfh);
+ unlink(tempf);
+}
+
+static void test_file_put_get( void )
+{
+ char* tempf;
+ FILE *tempfh;
+ static const char mytext[]= "This is a test_file_put_get\n";
+ static const char dostext[]= "This is a test_file_put_get\r\n";
+ char btext[LLEN];
+ WCHAR wtextW[LLEN+1];
+ WCHAR *mytextW = NULL, *aptr, *wptr;
+ BOOL diff_found = FALSE;
+ unsigned int i;
+
+ tempf=_tempnam(".","wne");
+ tempfh = fopen(tempf,"wt"); /* open in TEXT mode */
+ fputs(mytext,tempfh);
+ fclose(tempfh);
+ tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
+ fgets(btext,LLEN,tempfh);
+ ok( strlen(mytext) + 1 == strlen(btext),"TEXT/BINARY mode not handled for write\n");
+ ok( btext[strlen(mytext)-1] == '\r', "CR not written\n");
+ fclose(tempfh);
+ tempfh = fopen(tempf,"wb"); /* open in BINARY mode */
+ fputs(dostext,tempfh);
+ fclose(tempfh);
+ tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
+ fgets(btext,LLEN,tempfh);
+ ok(strcmp(btext, mytext) == 0,"_O_TEXT read doesn't strip CR\n");
+ fclose(tempfh);
+ tempfh = fopen(tempf,"rb"); /* open in TEXT mode */
+ fgets(btext,LLEN,tempfh);
+ ok(strcmp(btext, dostext) == 0,"_O_BINARY read doesn't preserve CR\n");
+
+ fclose(tempfh);
+ tempfh = fopen(tempf,"rt"); /* open in TEXT mode */
+ fgetws(wtextW,LLEN,tempfh);
+ mytextW = AtoW ((char*)mytext);
+ aptr = mytextW;
+ wptr = wtextW;
+
+ for (i=0; i<strlen(mytext); i++, aptr++, wptr++)
+ {
+ diff_found |= (*aptr != *wptr);
+ }
+ ok(!(diff_found), "fgetwc doesn't strip CR in TEXT mode\n");
+ if(mytextW) free (mytextW);
+ fclose(tempfh);
+ unlink(tempf);
+}
+
+static void test_file_write_read( void )
+{
+ char* tempf;
+ int tempfd;
+ static const char mytext[]= "This is test_file_write_read\nsecond line\n";
+ static const char dostext[]= "This is test_file_write_read\r\nsecond line\r\n";
+ char btext[LLEN];
+
+ tempf=_tempnam(".","wne");
+ ok((tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_TEXT|_O_RDWR,
+ _S_IREAD | _S_IWRITE)) != -1,
+ "Can't open '%s': %d\n", tempf, errno); /* open in TEXT mode */
+ ok(_write(tempfd,mytext,strlen(mytext)) == lstrlenA(mytext),
+ "_write _O_TEXT bad return value\n");
+ _close(tempfd);
+ tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
+ ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
+ "_read _O_BINARY got bad length\n");
+ ok( memcmp(dostext,btext,strlen(dostext)) == 0,
+ "problems with _O_TEXT _write / _O_BINARY _read\n");
+ ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
+ _close(tempfd);
+ tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
+ ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
+ "_read _O_TEXT got bad length\n");
+ ok( memcmp(mytext,btext,strlen(mytext)) == 0,
+ "problems with _O_TEXT _write / _read\n");
+ _close(tempfd);
+ ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno);
+
+ tempf=_tempnam(".","wne");
+ ok((tempfd = _open(tempf,_O_CREAT|_O_TRUNC|_O_BINARY|_O_RDWR,0)) != -1,
+ "Can't open '%s': %d\n", tempf, errno); /* open in BINARY mode */
+ ok(_write(tempfd,dostext,strlen(dostext)) == lstrlenA(dostext),
+ "_write _O_BINARY bad return value\n");
+ _close(tempfd);
+ tempfd = _open(tempf,_O_RDONLY|_O_BINARY,0); /* open in BINARY mode */
+ ok(_read(tempfd,btext,LLEN) == lstrlenA(dostext),
+ "_read _O_BINARY got bad length\n");
+ ok( memcmp(dostext,btext,strlen(dostext)) == 0,
+ "problems with _O_BINARY _write / _read\n");
+ ok( btext[strlen(dostext)-2] == '\r', "CR not written or read\n");
+ _close(tempfd);
+ tempfd = _open(tempf,_O_RDONLY|_O_TEXT); /* open in TEXT mode */
+ ok(_read(tempfd,btext,LLEN) == lstrlenA(mytext),
+ "_read _O_TEXT got bad length\n");
+ ok( memcmp(mytext,btext,strlen(mytext)) == 0,
+ "problems with _O_BINARY _write / _O_TEXT _read\n");
+ _close(tempfd);
+
+ ok(_chmod (tempf, _S_IREAD | _S_IWRITE) == 0,
+ "Can't chmod '%s' to read-write: %d\n", tempf, errno);
+ ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno);
+}
+
+static void test_file_inherit_child(const char* fd_s)
+{
+ int fd = atoi(fd_s);
+ char buffer[32];
+
+ ok(write(fd, "Success", 8) == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno));
+ lseek(fd, 0, SEEK_SET);
+ ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n");
+ ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
+}
+
+static void test_file_inherit_child_no(const char* fd_s)
+{
+ int fd = atoi(fd_s);
+
+ ok(write(fd, "Success", 8) == -1 && errno == EBADF,
+ "Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
+}
+
+static void test_file_inherit( const char* selfname )
+{
+ int fd;
+ const char* arg_v[5];
+ char buffer[16];
+
+ fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
+ ok(fd != -1, "Couldn't create test file\n ");
+ arg_v[0] = selfname;
+ arg_v[1] = "tests/file.c";
+ arg_v[2] = buffer; sprintf(buffer, "%d", fd);
+ arg_v[3] = 0;
+ _spawnvp(_P_WAIT, selfname, arg_v);
+ ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
+ lseek(fd, 0, SEEK_SET);
+ ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
+ close (fd);
+ ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
+
+ fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
+ ok(fd != -1, "Couldn't create test file\n ");
+ arg_v[0] = selfname;
+ arg_v[1] = "tests/file.c";
+ arg_v[2] = buffer; sprintf(buffer, "%d", fd);
+ arg_v[3] = buffer;
+ arg_v[4] = 0;
+ _spawnvp(_P_WAIT, selfname, arg_v);
+ ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
+ ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
+ close (fd);
+ ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
+}
+
+static void test_tmpnam( void )
+{
+ char name[MAX_PATH] = "abc";
+ char *res;
+
+ res = tmpnam(NULL);
+ ok(res != NULL, "tmpnam returned NULL\n");
+ ok(res[0] == '\\', "first character is not a backslash\n");
+ ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
+ ok(res[strlen(res)-1] == '.', "first call - last character is not a dot\n");
+
+ res = tmpnam(name);
+ ok(res != NULL, "tmpnam returned NULL\n");
+ ok(res == name, "supplied buffer was not used\n");
+ ok(res[0] == '\\', "first character is not a backslash\n");
+ ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
+ ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
+}
+
+
+
+START_TEST(file)
+{
+ int arg_c;
+ char** arg_v;
+
+ arg_c = winetest_get_mainargs( &arg_v );
+
+ if (arg_c >= 3)
+ {
+ if (arg_c == 3) test_file_inherit_child(arg_v[2]); else test_file_inherit_child_no(arg_v[2]);
+ return;
+ }
+
+ test_fdopen();
+ test_fileops();
+ test_fgetwc();
+ test_file_put_get();
+ test_file_write_read();
+ test_file_inherit(arg_v[0]);
+ test_tmpnam();
+}
reactos/lib/msvcrt/tests
diff -N heap.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ heap.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,42 @@
+/*
+ * Unit test suite for memory functions
+ *
+ * Copyright 2003 Dimitrie O. Paun
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include "wine/test.h"
+
+START_TEST(heap)
+{
+ void *mem;
+
+ mem = malloc(0);
+ ok(mem != NULL, "memory not allocated for size 0\n");
+
+ mem = realloc(NULL, 10);
+ ok(mem != NULL, "memory not allocated\n");
+
+ mem = realloc(mem, 20);
+ ok(mem != NULL, "memory not reallocated\n");
+
+ mem = realloc(mem, 0);
+ ok(mem == NULL, "memory not freed\n");
+
+ mem = realloc(NULL, 0);
+ ok(mem != NULL, "memory not (re)allocated for size 0\n");
+}
reactos/lib/msvcrt/tests
diff -N msvcrt_test.dsp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ msvcrt_test.dsp 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,107 @@
+# Microsoft Developer Studio Project File - Name="msvcrt_test" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=msvcrt_test - Win32 Wine Headers
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "msvcrt_test.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "msvcrt_test.mak" CFG="msvcrt_test - Win32 Wine Headers"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "msvcrt_test - Win32 MSVC Headers" (based on "Win32 (x86) Console Application")
+!MESSAGE "msvcrt_test - Win32 Wine Headers" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+!IF "$(CFG)" == "msvcrt_test - Win32 MSVC Headers"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Output\Win32_MSVC_Headers"
+# PROP BASE Intermediate_Dir "Output\Win32_MSVC_Headers"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output\Win32_MSVC_Headers"
+# PROP Intermediate_Dir "Output\Win32_MSVC_Headers"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ..\..\..\Output\\Win32_MSVC_Headers /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_MSVCRT_TEST_" /D "__WINE_USE_NATIVE_HEADERS" /D __WINETEST_OUTPUT_DIR=\"Output\\Win32_MSVC_Headers\" /D "__i386__" /D "_X86_" /D inline=__inline /FR /FD /GZ /c
+# ADD BASE RSC /l 0x41d /d "_DEBUG"
+# ADD RSC /l 0x41d /i "..\..\..\Output\\Win32_MSVC_Headers" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "msvcrt_test - Win32 Wine Headers"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Output\Win32_Wine_Headers"
+# PROP BASE Intermediate_Dir "Output\Win32_Wine_Headers"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Output\Win32_Wine_Headers"
+# PROP Intermediate_Dir "Output\Win32_Wine_Headers"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ..\..\..\Output\\Win32_Wine_Headers /I ..\..\..\include /D "WINVER=0x0501" /D "_WIN32_WINNT=0x0501" /D "_WIN32_IE=0x0600" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_MSVCRT_TEST_" /D __WINETEST_OUTPUT_DIR=\"Output\\Win32_Wine_Headers\" /D "__i386__" /D "_X86_" /D inline=__inline /FR /FD /GZ /c
+# ADD BASE RSC /l 0x41d /d "_DEBUG"
+# ADD RSC /l 0x41d /i "..\..\..\Output\\Win32_Wine_Headers" /i "..\..\..\include" /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "msvcrt_test - Win32 MSVC Headers"
+# Name "msvcrt_test - Win32 Wine Headers"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\cpp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\\
+# End Source File
+# Begin Source File
+
+SOURCE=.\testlist.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
reactos/lib/msvcrt/tests
diff -N printf.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ printf.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,151 @@
+/*
+ * Conformance tests for *printf functions.
+ *
+ * Copyright 2002 Uwe Bonnes
+ * Copyright 2004 Aneurin Price
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+
+#include "wine/test.h"
+
+static void test_sprintf( void )
+{
+ char buffer[100];
+ const char *I64d = "%I64d";
+ const char *O4c = "%04c";
+ const char *O4s = "%04s";
+ const char *hash012p = "%#012p";
+ double pnumber=789456123;
+/** WCHAR widestring[]={'w','i','d','e','s','t','r','i','n','g',0};**/
+ sprintf(buffer,"%+#23.15e",pnumber);
+ todo_wine
+ {
+ ok(strstr(buffer,"e+008") != 0,"Sprintf different \"%s\"\n",buffer);
+ }
+ sprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff);
+ todo_wine
+ {
+ ok(strlen(buffer) == 11,"Problem with long long \"%s\"\n",buffer);
+ }
+ sprintf(buffer,"%lld",((ULONGLONG)0xffffffff)*0xffffffff);
+ todo_wine
+ {
+ ok(strlen(buffer) == 1,"Problem with \"ll\" interpretation \"%s\"\n",buffer);
+ }
+/** This one actually crashes WINE at the moment, when using builtin msvcrt.dll.
+ sprintf(buffer,"%S",widestring);
+ todo_wine
+ {
+ ok(strlen(buffer) == 10,"Problem with \"%%S\" interpretation \"%s\"\n",buffer);
+ }
+ **/
+ sprintf(buffer,O4c,'1');
+ todo_wine
+ {
+ ok(!strcmp(buffer,"0001"),"Character not zero-prefixed \"%s\"\n",buffer);
+ }
+ sprintf(buffer,"%p",(void *)57);
+ todo_wine
+ {
+ ok(!strcmp(buffer,"00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
+ }
+ sprintf(buffer,hash012p,(void *)57);
+ todo_wine
+ {
+ ok(!strcmp(buffer," 0X00000039"),"Pointer formatted incorrectly \"%s\"\n",buffer);
+ }
+ sprintf(buffer,O4s,"foo");/**Warning again**/
+ todo_wine
+ {
+ ok(!strcmp(buffer,"0foo"),"String not zero-prefixed \"%s\"\n",buffer);
+ }
+}
+
+static void test_swprintf( void )
+{
+ wchar_t buffer[100];
+ const wchar_t I64d[] = {'%','I','6','4','d',0};
+ double pnumber=789456123;
+ const wchar_t TwentyThreePoint15e[]= {'%','+','#','2','3','.','1','5','e',0};
+ const wchar_t e008[] = {'e','+','0','0','8',0};
+ const char string[]={'s','t','r','i','n','g',0};
+ const wchar_t S[]={'%','S',0};
+ swprintf(buffer,TwentyThreePoint15e,pnumber);
+ todo_wine
+ {
+ ok(wcsstr(buffer,e008) != 0,"Sprintf different\n");
+ }
+ swprintf(buffer,I64d,((ULONGLONG)0xffffffff)*0xffffffff);
+ todo_wine
+ {
+ ok(wcslen(buffer) == 11,"Problem with long long\n");
+ }
+ swprintf(buffer,S,string);
+ ok(wcslen(buffer) == 6,"Problem with \"%%S\" interpretation\n");
+}
+
+static void test_fwprintf( void )
+{
+ const char *string="not a wide string";
+ todo_wine
+ {
+ ok(fwprintf(fopen("nul","r+"),(wchar_t *)string) == -1,"Non-wide string should not be printed by fwprintf\n");
+ }
+}
+
+static void test_snprintf (void)
+{
+ struct snprintf_test {
+ const char *format;
+ int expected;
+ struct {
+ int retval;
+ int render;
+ } todo;
+ };
+ /* Pre-2.1 libc behaviour, not C99 compliant. */
+ const struct snprintf_test tests[] = {{"short", 5, {0, 0}},
+ {"justfit", 7, {0, 0}},
+ {"justfits", 8, {0, 1}},
+ {"muchlonger", -1, {1, 1}}};
+ char buffer[8];
+ const int bufsiz = sizeof buffer;
+ unsigned int i;
+
+ for (i = 0; i < sizeof tests / sizeof tests[0]; i++) {
+ const char *fmt = tests[i].format;
+ const int expect = tests[i].expected;
+ const int n = _snprintf (buffer, bufsiz, fmt);
+ const int valid = n < 0 ? bufsiz : (n == bufsiz ? n : n+1);
+
+ todo (tests[i].todo.retval ? "wine" : "none")
+ ok (n == expect, "\"%s\": expected %d, returned %d\n",
+ fmt, expect, n);
+ todo (tests[i].todo.render ? "wine" : "none")
+ ok (!memcmp (fmt, buffer, valid),
+ "\"%s\": rendered \"%.*s\"\n", fmt, valid, buffer);
+ };
+}
+
+START_TEST(printf)
+{
+ test_sprintf();
+ test_swprintf();
+ test_fwprintf();
+ test_snprintf();
+}
reactos/lib/msvcrt/tests
diff -N scanf.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ scanf.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,103 @@
+/*
+ * Unit test suite for *scanf functions.
+ *
+ * Copyright 2002 Uwe Bonnes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+
+#include "wine/test.h"
+
+static void test_sscanf( void )
+{
+ char buffer[100], buffer1[100];
+ char format[20];
+ int result, ret;
+ float res1= -82.6267f, res2= 27.76f, res11, res12;
+ static const char pname[]=" St. Petersburg, Florida\n";
+ int hour=21,min=59,sec=20;
+ int number,number_so_far;
+
+
+ /* check EOF */
+ strcpy(buffer,"");
+ ret = sscanf(buffer, "%d", &result);
+ ok( ret == EOF,"sscanf returns %x instead of %x\n", ret, EOF );
+
+ /* check %x */
+ strcpy(buffer,"0x519");
+ ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
+ ok( result == 0x519,"sscanf reads %x instead of %x\n", result, 0x519 );
+
+ strcpy(buffer,"0x51a");
+ ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
+ ok( result == 0x51a ,"sscanf reads %x instead of %x\n", result, 0x51a );
+
+ strcpy(buffer,"0x51g");
+ ok( sscanf(buffer, "%x", &result) == 1, "sscanf failed\n" );
+ ok( result == 0x51, "sscanf reads %x instead of %x\n", result, 0x51 );
+
+ /* check % followed by any char */
+ strcpy(buffer,"\"%12@");
+ strcpy(format,"%\"%%%d%@"); /* work around gcc format check */
+ ok( sscanf(buffer, format, &result) == 1, "sscanf failed\n" );
+ ok( result == 12, "sscanf reads %x instead of %x\n", result, 12 );
+
+ /* Check float */
+ ret = sprintf(buffer,"%f %f",res1, res2);
+ ret = sscanf(buffer,"%f%f",&res11, &res12);
+ ok( (res11 == res1) && (res12 == res2), "Error reading floats\n");
+
+ /* check strings */
+ ret = sprintf(buffer," %s", pname);
+ ret = sscanf(buffer,"%*c%[^\n]",buffer1);
+ ok( ret == 1, "Error with format \"%s\"\n","%*c%[^\n]");
+ ok( strncmp(pname,buffer1,strlen(buffer1)) == 0, "Error with \"%s\" \"%s\"\n",pname, buffer1);
+
+ ret = sscanf("abcefgdh","%*[a-cg-e]%c",&buffer[0]);
+ ok( ret == 1, "Error with format \"%s\"\n","%*[a-cg-e]%c");
+ ok( buffer[0] == 'd', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]);
+
+ ret = sscanf("abcefgdh","%*[a-cd-dg-e]%c",&buffer[0]);
+ ok( ret == 1, "Error with format \"%s\"\n","%*[a-cd-dg-e]%c");
+ ok( buffer[0] == 'h', "Error with \"abcefgdh\" \"%c\"\n", buffer[0]);
+
+ /* check digits */
+ ret = sprintf(buffer,"%d:%d:%d",hour,min,sec);
+ ret = sscanf(buffer,"%d%n",&number,&number_so_far);
+ ok(ret == 1 , "problem with format arg \"%%d%%n\"\n");
+ ok(number == hour,"Read wrong arg %d instead of %d\n",number, hour);
+ ok(number_so_far == 2,"Read wrong arg for \"%%n\" %d instead of 2\n",number_so_far);
+
+ ret = sscanf(buffer+2,"%*c%n",&number_so_far);
+ ok(ret == 0 , "problem with format arg \"%%*c%%n\"\n");
+ ok(number_so_far == 1,"Read wrong arg for \"%%n\" %d instead of 2\n",number_so_far);
+
+ /* Check %i according to bug 1878 */
+ strcpy(buffer,"123");
+ ret = sscanf(buffer, "%i", &result);
+ ok( ret == 1 , "Wrong number of arguments read\n");
+ ok(result == 123, "Wrong number read\n");
+ ret = sscanf(buffer, "%d", &result);
+ ok( ret == 1 , "Wrong number of arguments read\n");
+ ok(result == 123, "Wrong number read\n");
+}
+
+START_TEST(scanf)
+{
+ test_sscanf();
+}
reactos/lib/msvcrt/tests
diff -N string.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ string.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,51 @@
+/*
+ * Unit test suite for string functions.
+ *
+ * Copyright 2004 Uwe Bonnes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+#include <string.h>
+#include <stdlib.h>
+
+static void* (*pmemcpy)(void *, const void *, size_t n);
+static int* (*pmemcmp)(void *, const void *, size_t n);
+
+#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
+#define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
+
+
+START_TEST(string)
+{
+ void *mem;
+ static const char xilstring[]="c:/xilinx";
+ int nLen=strlen(xilstring);
+ HMODULE hMsvcrt = LoadLibraryA("msvcrt.dll");
+ ok(hMsvcrt != 0, "LoadLibraryA failed\n");
+ SET(pmemcpy,"memcpy");
+ SET(pmemcmp,"memcmp");
+
+ /* MSVCRT memcpy behaves like memmove for overlapping moves,
+ MFC42 CString::Insert seems to rely on that behaviour */
+ mem = malloc(100);
+ ok(mem != NULL, "memory not allocated for size 0\n");
+ strcpy((char*)mem,xilstring);
+ pmemcpy((char*)mem+5, mem,nLen+1);
+ ok(pmemcmp((char*)mem+5,xilstring, nLen) == 0,
+ "Got result %s\n",(char*)mem+5);
+}
reactos/lib/msvcrt/tests
diff -N testlist.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testlist.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,39 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+/* stdarg.h is needed for Winelib */
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "windef.h"
+#include "winbase.h"
+
+extern void func_cpp(void);
+extern void func_environ(void);
+extern void func_file(void);
+extern void func_heap(void);
+extern void func_printf(void);
+extern void func_scanf(void);
+extern void func_string(void);
+extern void func_time(void);
+
+struct test
+{
+ const char *name;
+ void (*func)(void);
+};
+
+static const struct test winetest_testlist[] =
+{
+ { "cpp", func_cpp },
+ { "environ", func_environ },
+ { "file", func_file },
+ { "heap", func_heap },
+ { "printf", func_printf },
+ { "scanf", func_scanf },
+ { "string", func_string },
+ { "time", func_time },
+ { 0, 0 }
+};
+
+#define WINETEST_WANT_MAIN
+#include "wine/test.h"
reactos/lib/msvcrt/tests
diff -N time.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ time.c 13 Dec 2004 16:18:27 -0000 1.1.2.1
@@ -0,0 +1,189 @@
+/*
+ * Unit test suite for time functions.
+ *
+ * Copyright 2004 Uwe Bonnes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+#include "time.h"
+
+#include <stdlib.h> /*setenv*/
+#include <stdio.h> /*printf*/
+
+#define SECSPERDAY 86400
+#define SECSPERHOUR 3600
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+
+static void test_gmtime()
+{
+ time_t gmt = (time_t)NULL;
+ struct tm* gmt_tm = gmtime(&gmt);
+ if(gmt_tm == 0)
+ {
+ ok(0,"gmtime() error\n");
+ return;
+ }
+ ok(((gmt_tm->tm_year == 70) && (gmt_tm->tm_mon == 0) && (gmt_tm->tm_yday == 0) &&
+ (gmt_tm->tm_mday == 1) && (gmt_tm->tm_wday == 4) && (gmt_tm->tm_hour == 0) &&
+ (gmt_tm->tm_min == 0) && (gmt_tm->tm_sec == 0) && (gmt_tm->tm_isdst == 0)),
+ "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+ gmt_tm->tm_year, gmt_tm->tm_mon, gmt_tm->tm_yday, gmt_tm->tm_mday, gmt_tm->tm_wday,
+ gmt_tm->tm_hour, gmt_tm->tm_min, gmt_tm->tm_sec, gmt_tm->tm_isdst);
+
+}
+static void test_mktime()
+{
+ TIME_ZONE_INFORMATION tzinfo;
+ DWORD res = GetTimeZoneInformation(&tzinfo);
+ struct tm my_tm, sav_tm;
+ time_t nulltime, local_time;
+ char TZ_env[256];
+ int secs;
+
+ ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
+ /* Bias may be positive or negative, to use offset of one day */
+ secs= SECSPERDAY - (tzinfo.Bias +
+ ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
+ ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * SECSPERMIN;
+ my_tm.tm_mday = 1 + secs/SECSPERDAY;
+ secs = secs % SECSPERDAY;
+ my_tm.tm_hour = secs / SECSPERHOUR;
+ secs = secs % SECSPERHOUR;
+ my_tm.tm_min = secs / SECSPERMIN;
+ secs = secs % SECSPERMIN;
+ my_tm.tm_sec = secs;
+
+ my_tm.tm_year = 70;
+ my_tm.tm_mon = 0;
+ my_tm.tm_isdst= 0;
+
+ sav_tm = my_tm;
+
+ local_time = mktime(&my_tm);
+ ok(((DWORD)local_time == SECSPERDAY), "mktime returned 0x%08lx\n",(DWORD)local_time);
+ /* now test some unnormalized struct tm's */
+ my_tm = sav_tm;
+ my_tm.tm_sec += 60;
+ my_tm.tm_min -= 1;
+ local_time = mktime(&my_tm);
+ ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+ ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+ my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+ my_tm.tm_sec == sav_tm.tm_sec
+ , "mktime returned %3d-%02d-%02d %02d:%02d expected %3d-%02d-%02d %02d:%02d.\n",
+ my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+ my_tm.tm_hour,my_tm.tm_sec,
+ sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+ sav_tm.tm_hour,sav_tm.tm_sec);
+ my_tm = sav_tm;
+ my_tm.tm_min -= 60;
+ my_tm.tm_hour += 1;
+ local_time = mktime(&my_tm);
+ ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+ ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+ my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+ my_tm.tm_sec == sav_tm.tm_sec
+ , "mktime returned %3d-%02d-%02d %02d:%02d expected %3d-%02d-%02d %02d:%02d.\n",
+ my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+ my_tm.tm_hour,my_tm.tm_sec,
+ sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+ sav_tm.tm_hour,sav_tm.tm_sec);
+ my_tm = sav_tm;
+ my_tm.tm_mon -= 12;
+ my_tm.tm_year += 1;
+ local_time = mktime(&my_tm);
+ ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+ ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+ my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+ my_tm.tm_sec == sav_tm.tm_sec
+ , "mktime returned %3d-%02d-%02d %02d:%02d expected %3d-%02d-%02d %02d:%02d.\n",
+ my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+ my_tm.tm_hour,my_tm.tm_sec,
+ sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+ sav_tm.tm_hour,sav_tm.tm_sec);
+ my_tm = sav_tm;
+ my_tm.tm_mon += 12;
+ my_tm.tm_year -= 1;
+ local_time = mktime(&my_tm);
+ ok(((DWORD)local_time == SECSPERDAY), "Unnormalized mktime returned 0x%08lx\n",(DWORD)local_time);
+ ok( my_tm.tm_year == sav_tm.tm_year && my_tm.tm_mon == sav_tm.tm_mon &&
+ my_tm.tm_mday == sav_tm.tm_mday && my_tm.tm_hour == sav_tm.tm_hour &&
+ my_tm.tm_sec == sav_tm.tm_sec
+ , "mktime returned %3d-%02d-%02d %02d:%02d expected %3d-%02d-%02d %02d:%02d.\n",
+ my_tm.tm_year,my_tm.tm_mon,my_tm.tm_mday,
+ my_tm.tm_hour,my_tm.tm_sec,
+ sav_tm.tm_year,sav_tm.tm_mon,sav_tm.tm_mday,
+ sav_tm.tm_hour,sav_tm.tm_sec);
+ /* now a bad time example */
+ my_tm = sav_tm;
+ my_tm.tm_year -= 1;
+ local_time = mktime(&my_tm);
+ ok((local_time == -1), "(bad time) mktime returned 0x%08lx\n",(DWORD)local_time);
+
+ my_tm = sav_tm;
+ /* TEST that we are independent from the TZ variable */
+ /*Argh, msvcrt doesn't have setenv() */
+ _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
+ putenv("TZ=GMT");
+ nulltime = mktime(&my_tm);
+ ok(((DWORD)nulltime == SECSPERDAY),"mktime returned 0x%08lx\n",(DWORD)nulltime);
+ putenv(TZ_env);
+}
+static void test_localtime()
+{
+ TIME_ZONE_INFORMATION tzinfo;
+ DWORD res = GetTimeZoneInformation(&tzinfo);
+ time_t gmt = (time_t)(SECSPERDAY + (tzinfo.Bias +
+ ( res == TIME_ZONE_ID_STANDARD ? tzinfo.StandardBias :
+ ( res == TIME_ZONE_ID_DAYLIGHT ? tzinfo.DaylightBias : 0 ))) * SECSPERMIN);
+
+ char TZ_env[256];
+ struct tm* lt;
+
+ ok (res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
+ lt = localtime(&gmt);
+ ok(((lt->tm_year == 70) && (lt->tm_mon == 0) && (lt->tm_yday == 1) &&
+ (lt->tm_mday == 2) && (lt->tm_wday == 5) && (lt->tm_hour == 0) &&
+ (lt->tm_min == 0) && (lt->tm_sec == 0) && (lt->tm_isdst ==
+ (res == TIME_ZONE_ID_DAYLIGHT))),
+ "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+ lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour,
+ lt->tm_min, lt->tm_sec, lt->tm_isdst);
+
+ _snprintf(TZ_env,255,"TZ=%s",(getenv("TZ")?getenv("TZ"):""));
+ putenv("TZ=GMT");
+ lt = localtime(&gmt);
+ ok(((lt->tm_year == 70) && (lt->tm_mon == 0) && (lt->tm_yday == 1) &&
+ (lt->tm_mday == 2) && (lt->tm_wday == 5) && (lt->tm_hour == 0) &&
+ (lt->tm_min == 0) && (lt->tm_sec == 0) && (lt->tm_isdst ==
+ (res == TIME_ZONE_ID_DAYLIGHT))),
+ "Wrong date:Year %4d mon %2d yday %3d mday %2d wday %1d hour%2d min %2d sec %2d dst %2d\n",
+ lt->tm_year, lt->tm_mon, lt->tm_yday, lt->tm_mday, lt->tm_wday, lt->tm_hour,
+ lt->tm_min, lt->tm_sec, lt->tm_isdst);
+ putenv(TZ_env);
+}
+
+
+START_TEST(time)
+{
+ test_gmtime();
+ test_mktime();
+ test_localtime();
+}
CVSspam 0.2.8