/*
 * Copyright 1997 Bruce Milner
 * Copyright 1998 Andreas Mohr
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "aspi.h"
#include "wnaspi32.h"
#include "winescsi.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(aspi);

/* FIXME!
 * 1) Residual byte length reporting not handled
 * 2) Make this code re-entrant for multithreading
 *    -- Added CriticalSection to OpenDevices function
 * 3) Only linux supported so far
 * 4) Leaves sg devices open. This may or may not be okay.  A better solution
 *    would be to close the file descriptors when the thread/process using
 *    them no longer needs them.
 */

#ifdef linux

static ASPI_DEVICE_INFO *ASPI_open_devices = NULL;

static CRITICAL_SECTION ASPI_CritSection;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &ASPI_CritSection,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": ASPI_CritSection") }
};
static CRITICAL_SECTION ASPI_CritSection = { &critsect_debug, -1, 0, 0, 0, 0 };

#endif /* defined(linux) */


BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
{
#ifdef linux
	switch( fdwReason )
	{
	case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hInstDLL);
            SCSI_Init();
            break;
	case DLL_PROCESS_DETACH:
            DeleteCriticalSection( &ASPI_CritSection );
            break;
	}
#endif /* defined(linux) */
	return TRUE;
}


#ifdef linux

static int
ASPI_OpenDevice(SRB_ExecSCSICmd *prb)
{
    int	fd;
    DWORD	hc;
    ASPI_DEVICE_INFO *curr;

    /* search list of devices to see if we've opened it already.
     * There is not an explicit open/close in ASPI land, so hopefully
     * keeping a device open won't be a problem.
     */

    EnterCriticalSection(&ASPI_CritSection);
    for (curr = ASPI_open_devices; curr; curr = curr->next) {
	if (curr->hostId == prb->SRB_HaId &&
	    curr->target == prb->SRB_Target &&
	    curr->lun == prb->SRB_Lun) {
            LeaveCriticalSection(&ASPI_CritSection);
	    return curr->fd;
	}
    }
    LeaveCriticalSection(&ASPI_CritSection);

    if (prb->SRB_HaId > ASPI_GetNumControllers())
	return -1;

    hc = ASPI_GetHCforController( prb->SRB_HaId );
    fd = SCSI_OpenDevice( HIWORD(hc), LOWORD(hc), prb->SRB_Target, prb->SRB_Lun);

    if (fd == -1)
	return -1;

    /* device is now open */
    /* FIXME: Let users specify SCSI timeout in registry */
    SCSI_LinuxSetTimeout( fd, SCSI_DEFAULT_TIMEOUT );

    curr = HeapAlloc( GetProcessHeap(), 0, sizeof(ASPI_DEVICE_INFO) );
    curr->fd = fd;
    curr->hostId = prb->SRB_HaId;
    curr->target = prb->SRB_Target;
    curr->lun = prb->SRB_Lun;

    /* insert new record at beginning of open device list */
    EnterCriticalSection(&ASPI_CritSection);
    curr->next = ASPI_open_devices;
    ASPI_open_devices = curr;
    LeaveCriticalSection(&ASPI_CritSection);
    return fd;
}


static void
ASPI_DebugPrintCmd(SRB_ExecSCSICmd *prb)
{
  BYTE	cmd;
  int	i;
  BYTE *cdb;

  switch (prb->CDBByte[0]) {
  case CMD_INQUIRY:
    TRACE("INQUIRY {\n");
    TRACE("\tEVPD: %d\n", prb->CDBByte[1] & 1);
    TRACE("\tLUN: %d\n", (prb->CDBByte[1] & 0xc) >> 1);
    TRACE("\tPAGE CODE: %d\n", prb->CDBByte[2]);
    TRACE("\tALLOCATION LENGTH: %d\n", prb->CDBByte[4]);
    TRACE("\tCONTROL: %d\n", prb->CDBByte[5]);
    TRACE("}\n");
    break;
  case CMD_SCAN_SCAN:
    TRACE("Transfer Length: %d\n", prb->CDBByte[4]);
    break;
  }

  TRACE("Host Adapter: %d\n", prb->SRB_HaId);
  TRACE("Flags: %d\n", prb->SRB_Flags);
  if (TARGET_TO_HOST(prb)) {
    TRACE("\tData transfer: Target to host. Length checked.\n");
  }
  else if (HOST_TO_TARGET(prb)) {
    TRACE("\tData transfer: Host to target. Length checked.\n");
  }
  else if (NO_DATA_TRANSFERRED(prb)) {
    TRACE("\tData transfer: none\n");
  }
  else {
    WARN("\tTransfer by scsi cmd. Length not checked.\n");
  }

  TRACE("\tResidual byte length reporting %s\n", prb->SRB_Flags & 0x4 ? "enabled" : "disabled");
  TRACE("\tLinking %s\n", prb->SRB_Flags & 0x2 ? "enabled" : "disabled");
  TRACE("\tPosting %s\n", prb->SRB_Flags & 0x1 ? "enabled" : "disabled");
  TRACE("Target: %d\n", prb->SRB_Target);
  TRACE("Lun: %d\n", prb->SRB_Lun);
  TRACE("BufLen: %ld\n", prb->SRB_BufLen);
  TRACE("SenseLen: %d\n", prb->SRB_SenseLen);
  TRACE("BufPtr: %p\n", prb->SRB_BufPointer);
  TRACE("CDB Length: %d\n", prb->SRB_CDBLen);
  TRACE("POST Proc: %p\n", prb->SRB_PostProc);
  cdb = &prb->CDBByte[0];
  cmd = prb->CDBByte[0];
  if (TRACE_ON(aspi)) {
      TRACE("CDB buffer[");
      for (i = 0; i < prb->SRB_CDBLen; i++) {
          if (i != 0) TRACE(",");
          TRACE("%02x", *cdb++);
      }
      TRACE("]\n");
  }
}

static void
ASPI_PrintCDBArea(SRB_ExecSCSICmd *prb)
{
    if (TRACE_ON(aspi))
    {
	int i;
        TRACE("CDB[");
        for (i = 0; i < prb->SRB_CDBLen; i++) {
            if (i) TRACE(",");
            TRACE("%02x", prb->CDBByte[i]);
        }
        TRACE("]\n");
    }
}

static void
ASPI_PrintSenseArea(SRB_ExecSCSICmd *prb)
{
  int	i;
  BYTE	*rqbuf = prb->SenseArea;

  if (TRACE_ON(aspi))
  {
      TRACE("Request Sense reports:\n");
      if ((rqbuf[0]&0x7f)!=0x70) {
	      TRACE("\tInvalid sense header: 0x%02x instead of 0x70\n", rqbuf[0]&0x7f);
	      return;
      }
      TRACE("\tCurrent command read filemark: %s\n",(rqbuf[2]&0x80)?"yes":"no");
      TRACE("\tEarly warning passed: %s\n",(rqbuf[2]&0x40)?"yes":"no");
      TRACE("\tIncorrect blocklength: %s\n",(rqbuf[2]&0x20)?"yes":"no");
      TRACE("\tSense Key: %d\n",rqbuf[2]&0xf);
      if (rqbuf[0]&0x80)
	TRACE("\tResidual Length: %d\n",rqbuf[3]*0x1000000+rqbuf[4]*0x10000+rqbuf[5]*0x100+rqbuf[6]);
      TRACE("\tAdditional Sense Length: %d\n",rqbuf[7]);
      TRACE("\tAdditional Sense Code: %d\n",rqbuf[12]);
      TRACE("\tAdditional Sense Code Qualifier: %d\n",rqbuf[13]);
      if (rqbuf[15]&0x80) {
	TRACE("\tIllegal Param is in %s\n",(rqbuf[15]&0x40)?"the CDB":"the Data Out Phase");
	if (rqbuf[15]&0x8) {
	  TRACE("Pointer at %d, bit %d\n",rqbuf[16]*256+rqbuf[17],rqbuf[15]&0x7);
	}
      }
      TRACE("SenseArea[");
      for (i = 0; i < prb->SRB_SenseLen; i++) {
	if (i) TRACE(",");
	TRACE("%02x", *rqbuf++);
      }
      TRACE("]\n");
  }
}

static void
ASPI_DebugPrintResult(SRB_ExecSCSICmd *prb)
{

  TRACE("SRB_Status: %x\n", prb->SRB_Status);
  TRACE("SRB_HaStat: %x\n", prb->SRB_HaStat);
  TRACE("SRB_TargStat: %x\n", prb->SRB_TargStat);
  switch (prb->CDBByte[0]) {
  case CMD_INQUIRY:
    TRACE("Vendor: '%s'\n", prb->SRB_BufPointer + INQUIRY_VENDOR);
    break;
  case CMD_TEST_UNIT_READY:
    ASPI_PrintSenseArea(prb);
    break;
  }
}

/* Posting must be done in such a way that as soon as the SRB_Status is set
 * we don't touch the SRB anymore because it could possibly be freed
 * if the app is doing ASPI polling
 */
static DWORD
WNASPI32_DoPosting( SRB_ExecSCSICmd *lpPRB, DWORD status )
{
	void (*SRB_PostProc)() = lpPRB->SRB_PostProc;
	BYTE SRB_Flags = lpPRB->SRB_Flags;
	if( status == SS_PENDING )
	{
		WARN("Tried posting SS_PENDING\n");
		return SS_PENDING;
	}
	lpPRB->SRB_Status = status;
	/* lpPRB is NOT safe, it could be freed in another thread */

	if (SRB_PostProc)
	{
		if (SRB_Flags & 0x1)
		{
			TRACE("Post Routine (%p) called\n", SRB_PostProc);
			/* Even though lpPRB could have been freed by
			 * the program.. that's unlikely if it planned
			 * to use it in the PostProc
			 */
			(*SRB_PostProc)(lpPRB);
		}
		else if (SRB_Flags & SRB_EVENT_NOTIFY) {
			TRACE("Setting event %p\n", (HANDLE)SRB_PostProc);
			SetEvent((HANDLE)SRB_PostProc);
		}
	}
	return SS_PENDING;
}

static WORD
ASPI_ExecScsiCmd(SRB_ExecSCSICmd *lpPRB)
{
  struct sg_header *sg_hd, *sg_reply_hdr;
  WORD ret;
  DWORD	status;
  int	in_len, out_len;
  int	error_code = 0;
  int	fd;
  DWORD SRB_Status;

  /* FIXME: hackmode */
#define MAKE_TARGET_TO_HOST(lpPRB) \
  	if (!TARGET_TO_HOST(lpPRB)) { \
	    WARN("program was not sending target_to_host for cmd %x (flags=%x),correcting.\n",lpPRB->CDBByte[0],lpPRB->SRB_Flags); \
	    lpPRB->SRB_Flags |= 0x08; \
	}
#define MAKE_HOST_TO_TARGET(lpPRB) \
  	if (!HOST_TO_TARGET(lpPRB)) { \
	    WARN("program was not sending host_to_target for cmd %x (flags=%x),correcting.\n",lpPRB->CDBByte[0],lpPRB->SRB_Flags); \
	    lpPRB->SRB_Flags |= 0x10; \
	}
  switch (lpPRB->CDBByte[0]) {
  case 0x12: /* INQUIRY */
  case 0x5a: /* MODE_SENSE_10 */
  case 0xa4: /* REPORT_KEY (DVD) MMC-2 */
  case 0xad: /* READ DVD STRUCTURE MMC-2 */
        MAKE_TARGET_TO_HOST(lpPRB)
	break;
  case 0xa3: /* SEND KEY (DVD) MMC-2 */
        MAKE_HOST_TO_TARGET(lpPRB)
	break;
  default:
	if ((((lpPRB->SRB_Flags & 0x18) == 0x00) ||
	     ((lpPRB->SRB_Flags & 0x18) == 0x18)
	    ) && lpPRB->SRB_BufLen
	) {
	    FIXME("command 0x%02x, no data transfer specified, but buflen is %ld!!!\n",lpPRB->CDBByte[0],lpPRB->SRB_BufLen);
	}
	break;
  }
  ASPI_DebugPrintCmd(lpPRB);
  if (lpPRB->SRB_HaId > ASPI_GetNumControllers()) {
      ERR("Failed: Wanted hostadapter %d, but we have only %d.\n",
	  lpPRB->SRB_HaId,ASPI_GetNumControllers()
      );
      return WNASPI32_DoPosting( lpPRB, SS_INVALID_HA );
  }
  fd = ASPI_OpenDevice(lpPRB);
  if (fd == -1) {
      return WNASPI32_DoPosting( lpPRB, SS_NO_DEVICE );
  }

  sg_hd = NULL;
  sg_reply_hdr = NULL;

  lpPRB->SRB_Status = SS_PENDING;

  if (!lpPRB->SRB_CDBLen) {
      ERR("Failed: lpPRB->SRB_CDBLen = 0.\n");
      return WNASPI32_DoPosting( lpPRB, SS_INVALID_SRB );
  }

  /* build up sg_header + scsi cmd */
  if (HOST_TO_TARGET(lpPRB)) {
    /* send header, command, and then data */
    in_len = SCSI_OFF + lpPRB->SRB_CDBLen + lpPRB->SRB_BufLen;
    sg_hd = HeapAlloc(GetProcessHeap(), 0, in_len);
    memset(sg_hd, 0, SCSI_OFF);
    memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
    if (lpPRB->SRB_BufLen) {
      memcpy(((BYTE *) sg_hd) + SCSI_OFF + lpPRB->SRB_CDBLen, lpPRB->SRB_BufPointer, lpPRB->SRB_BufLen);
    }
  }
  else {
    /* send header and command - no data */
    in_len = SCSI_OFF + lpPRB->SRB_CDBLen;
    sg_hd = HeapAlloc(GetProcessHeap(), 0, in_len);
    memset(sg_hd, 0, SCSI_OFF);
    memcpy(sg_hd + 1, &lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);
  }

  if (TARGET_TO_HOST(lpPRB)) {
    out_len = SCSI_OFF + lpPRB->SRB_BufLen;
    sg_reply_hdr = HeapAlloc(GetProcessHeap(), 0, out_len);
    memset(sg_reply_hdr, 0, SCSI_OFF);
    sg_hd->reply_len = out_len;
  }
  else {
    out_len = SCSI_OFF;
    sg_reply_hdr = HeapAlloc(GetProcessHeap(), 0, out_len);
    memset(sg_reply_hdr, 0, SCSI_OFF);
    sg_hd->reply_len = out_len;
  }

  SCSI_Fix_CMD_LEN(fd, lpPRB->CDBByte[0], lpPRB->SRB_CDBLen);

  if(!SCSI_LinuxDeviceIo( fd,
			  sg_hd, in_len,
			  sg_reply_hdr, out_len,
			  &status) )
  {
    goto error_exit;
  }

  if (sg_reply_hdr->result != 0) {
    error_code = sg_reply_hdr->result;
    WARN("reply header error (%d)\n", sg_reply_hdr->result);
    goto error_exit;
  }

  if (TARGET_TO_HOST(lpPRB) && lpPRB->SRB_BufLen) {
    memcpy(lpPRB->SRB_BufPointer, sg_reply_hdr + 1, lpPRB->SRB_BufLen);
  }

  /* copy in sense buffer to amount that is available in client */
  if (lpPRB->SRB_SenseLen) {
    int sense_len = lpPRB->SRB_SenseLen;
    if (lpPRB->SRB_SenseLen > 16)
      sense_len = 16;

    /* CDB is fixed in WNASPI32 */
    memcpy(lpPRB->SenseArea, &sg_reply_hdr->sense_buffer[0], sense_len);

    ASPI_PrintCDBArea(lpPRB);
    ASPI_PrintSenseArea(lpPRB);
  }

  SRB_Status = SS_COMP;
  lpPRB->SRB_HaStat = HASTAT_OK;
  lpPRB->SRB_TargStat = sg_reply_hdr->target_status << 1;

  HeapFree(GetProcessHeap(), 0, sg_reply_hdr);
  HeapFree(GetProcessHeap(), 0, sg_hd);

  /* FIXME: Should this be != 0 maybe? */
  if( lpPRB->SRB_TargStat == 2 ) {
    SRB_Status = SS_ERR;
    switch (lpPRB->CDBByte[0]) {
    case 0xa4: /* REPORT_KEY (DVD) MMC-2 */
    case 0xa3: /* SEND KEY (DVD) MMC-2 */
          SRB_Status = SS_COMP;
	  lpPRB->SRB_TargStat = 0;
	  FIXME("Program wants to do DVD Region switching, but fails (non compliant DVD drive). Ignoring....\n");
	  break;
    }
  }

  ASPI_DebugPrintResult(lpPRB);
  /* now do posting */
  ret = WNASPI32_DoPosting( lpPRB, SRB_Status );

  switch (lpPRB->CDBByte[0]) {
  case CMD_INQUIRY:
      if (SRB_Status == SS_COMP)
	  return SS_COMP; /* some junk expects ss_comp here. */
      /*FALLTHROUGH*/
  default:
      break;
  }

  /* In real WNASPI32 stuff really is always pending because ASPI does things
     in the background, but we are not doing that (yet) */

  return ret;

error_exit:
  SRB_Status = SS_ERR;
  if (error_code == EBUSY) {
      WNASPI32_DoPosting( lpPRB, SS_ASPI_IS_BUSY );
      TRACE("Device busy\n");
  } else
      FIXME("Failed\n");

  /* I'm not sure exactly error codes work here
   * We probably should set lpPRB->SRB_TargStat, SRB_HaStat ?
   */
  WARN("error_exit\n");
  HeapFree(GetProcessHeap(), 0, sg_reply_hdr);
  HeapFree(GetProcessHeap(), 0, sg_hd);
  WNASPI32_DoPosting( lpPRB, SRB_Status );
  return SS_PENDING;
}

#endif /* defined(linux) */


/*******************************************************************
 *     GetASPI32SupportInfo		[WNASPI32.1]
 *
 * Checks if the ASPI subsystem is initialized correctly.
 *
 * RETURNS
 *    HIWORD: 0.
 *    HIBYTE of LOWORD: status (SS_COMP or SS_FAILED_INIT)
 *    LOBYTE of LOWORD: # of host adapters.
 */
DWORD __cdecl GetASPI32SupportInfo(void)
{
    DWORD controllers = ASPI_GetNumControllers();

    if (!controllers)
	return SS_NO_ADAPTERS << 8;
    return (SS_COMP << 8) | controllers ;
}

/***********************************************************************
 *             SendASPI32Command (WNASPI32.2)
 */
DWORD __cdecl SendASPI32Command(LPSRB lpSRB)
{
#ifdef linux
  static const char szId[] = "ASPI for WIN32";
  static const char szWh[] = "Wine host";
  switch (lpSRB->common.SRB_Cmd) {
  case SC_HA_INQUIRY:
    lpSRB->inquiry.SRB_Status = SS_COMP;       /* completed successfully */
    lpSRB->inquiry.HA_Count = ASPI_GetNumControllers();
    lpSRB->inquiry.HA_SCSI_ID = 7;             /* not always ID 7 */
    memcpy(lpSRB->inquiry.HA_ManagerId, szId, sizeof szId); /* max 15 chars, don't change */
    memcpy(lpSRB->inquiry.HA_Identifier, szWh, sizeof szWh); /* FIXME: return host adapter name */
    memset(lpSRB->inquiry.HA_Unique, 0, 16); /* default HA_Unique content */
    lpSRB->inquiry.HA_Unique[6] = 0x02; /* Maximum Transfer Length (128K, Byte> 4-7) */
    lpSRB->inquiry.HA_Unique[3] = 0x08; /* Maximum number of SCSI targets */
    FIXME("ASPI: Partially implemented SC_HA_INQUIRY for adapter %d.\n", lpSRB->inquiry.SRB_HaId);
    return SS_COMP;

  case SC_GET_DEV_TYPE: {
    /* FIXME: We should return SS_NO_DEVICE if the device is not configured */
    /* FIXME: We should return SS_INVALID_HA if HostAdapter!=0 */
    SRB		tmpsrb;
    unsigned char inqbuf[200];
    DWORD	ret;

    memset(&tmpsrb,0,sizeof(tmpsrb));

    /* Copy header */
    memcpy(&tmpsrb.common,&(lpSRB->common),sizeof(tmpsrb.common));

    tmpsrb.cmd.SRB_Flags	|= 8; /* target to host */
    tmpsrb.cmd.SRB_Cmd 		= SC_EXEC_SCSI_CMD;
    tmpsrb.cmd.SRB_Target	= lpSRB->devtype.SRB_Target;
    tmpsrb.cmd.SRB_Lun		= lpSRB->devtype.SRB_Lun;
    tmpsrb.cmd.SRB_BufLen	= sizeof(inqbuf);
    tmpsrb.cmd.SRB_BufPointer	= inqbuf;
    tmpsrb.cmd.CDBByte[0]	= 0x12; /* INQUIRY  */
    				  /* FIXME: handle lun */
    tmpsrb.cmd.CDBByte[4]	= sizeof(inqbuf);
    tmpsrb.cmd.SRB_CDBLen	= 6;

    ret = ASPI_ExecScsiCmd(&tmpsrb.cmd);

    lpSRB->devtype.SRB_Status	= tmpsrb.cmd.SRB_Status;
    lpSRB->devtype.SRB_DeviceType = inqbuf[0]&0x1f;

    TRACE("returning devicetype %d for target %d\n",inqbuf[0]&0x1f,tmpsrb.cmd.SRB_Target);
    if (ret!=SS_PENDING) /* Any error is passed down directly */
	return ret;
    /* FIXME: knows that the command is finished already, pass final Status */
    return tmpsrb.cmd.SRB_Status;
  }
  case SC_EXEC_SCSI_CMD:
    return ASPI_ExecScsiCmd(&lpSRB->cmd);
  case SC_ABORT_SRB:
    FIXME("Not implemented SC_ABORT_SRB\n");
    break;
  case SC_RESET_DEV:
    FIXME("Not implemented SC_RESET_DEV\n");
    break;
  case SC_GET_DISK_INFO:
    /* here we have to find out the int13 / bios association.
     * We just say we do not have any.
     */
    FIXME("SC_GET_DISK_INFO always return 'int13 unassociated disk'.\n");
    lpSRB->diskinfo.SRB_DriveFlags = 0; /* disk is not int13 served */
    return SS_COMP;
  default:
    FIXME("Unknown command %d\n", lpSRB->common.SRB_Cmd);
  }
  return SS_INVALID_SRB;
#else
  return SS_INVALID_SRB;
#endif
}


/***********************************************************************
 *             GetASPI32DLLVersion   (WNASPI32.4)
 */
DWORD __cdecl GetASPI32DLLVersion(void)
{
#ifdef linux
	TRACE("Returning version 1\n");
        return (DWORD)1;
#else
	FIXME("Please add SCSI support for your operating system, returning 0\n");
        return (DWORD)0;
#endif
}

/***********************************************************************
 *             GetASPI32Buffer   (WNASPI32.8)
 * Supposed to return a DMA capable large SCSI buffer.
 * Our implementation does not use those at all, all buffer stuff is
 * done in the kernel SG device layer. So we just heapalloc the buffer.
 */
BOOL __cdecl GetASPI32Buffer(PASPI32BUFF pab)
{
    pab->AB_BufPointer = HeapAlloc(GetProcessHeap(),
	    	pab->AB_ZeroFill?HEAP_ZERO_MEMORY:0,
		pab->AB_BufLen
    );
    if (!pab->AB_BufPointer) return FALSE;
    return TRUE;
}

/***********************************************************************
 *             FreeASPI32Buffer   (WNASPI32.14)
 */
BOOL __cdecl FreeASPI32Buffer(PASPI32BUFF pab)
{
    HeapFree(GetProcessHeap(),0,pab->AB_BufPointer);
    return TRUE;
}

/***********************************************************************
 *             TranslateASPI32Address   (WNASPI32.7)
 */
BOOL __cdecl TranslateASPI32Address(LPDWORD pdwPath, LPDWORD pdwDEVNODE)
{
    FIXME("(%p, %p), stub !\n", pdwPath, pdwDEVNODE);
    return TRUE;
}
