/*
 * NtDll debug buffer functions
 *
 * Copyright 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winnt.h"
#include "winternl.h"
#include "ntdll_misc.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(debug_buffer);

static void dump_DEBUG_MODULE_INFORMATION(const DEBUG_MODULE_INFORMATION *iBuf)
{
  TRACE( "MODULE_INFORMATION:%p\n", iBuf );
  if (NULL == iBuf) return ;
  TRACE( "Base:%d\n", iBuf->Base );
  TRACE( "Size:%d\n", iBuf->Size );
  TRACE( "Flags:%d\n", iBuf->Flags );
}

static void dump_DEBUG_HEAP_INFORMATION(const DEBUG_HEAP_INFORMATION *iBuf)
{
  TRACE( "HEAP_INFORMATION:%p\n", iBuf );
  if (NULL == iBuf) return ;
  TRACE( "Base:%d\n", iBuf->Base );
  TRACE( "Flags:%d\n", iBuf->Flags );
}

static void dump_DEBUG_LOCK_INFORMATION(const DEBUG_LOCK_INFORMATION *iBuf)
{
  TRACE( "LOCK_INFORMATION:%p\n", iBuf );

  if (NULL == iBuf) return ;

  TRACE( "Address:%p\n", iBuf->Address );
  TRACE( "Type:%d\n", iBuf->Type );
  TRACE( "CreatorBackTraceIndex:%d\n", iBuf->CreatorBackTraceIndex );
  TRACE( "OwnerThreadId:%d\n", iBuf->OwnerThreadId );
  TRACE( "ActiveCount:%d\n", iBuf->ActiveCount );
  TRACE( "ContentionCount:%d\n", iBuf->ContentionCount );
  TRACE( "EntryCount:%d\n", iBuf->EntryCount );
  TRACE( "RecursionCount:%d\n", iBuf->RecursionCount );
  TRACE( "NumberOfSharedWaiters:%d\n", iBuf->NumberOfSharedWaiters );
  TRACE( "NumberOfExclusiveWaiters:%d\n", iBuf->NumberOfExclusiveWaiters );
}

static void dump_DEBUG_BUFFER(const DEBUG_BUFFER *iBuf)
{
  if (NULL == iBuf) return ;
  TRACE( "SectionHandle:%p\n", iBuf->SectionHandle);
  TRACE( "SectionBase:%p\n", iBuf->SectionBase);
  TRACE( "RemoteSectionBase:%p\n", iBuf->RemoteSectionBase);
  TRACE( "SectionBaseDelta:%d\n", iBuf->SectionBaseDelta);
  TRACE( "EventPairHandle:%p\n", iBuf->EventPairHandle);
  TRACE( "RemoteThreadHandle:%p\n", iBuf->RemoteThreadHandle);
  TRACE( "InfoClassMask:%x\n", iBuf->InfoClassMask);
  TRACE( "SizeOfInfo:%d\n", iBuf->SizeOfInfo);
  TRACE( "AllocatedSize:%d\n", iBuf->AllocatedSize);
  TRACE( "SectionSize:%d\n", iBuf->SectionSize);
  TRACE( "BackTraceInfo:%p\n", iBuf->BackTraceInformation);
  dump_DEBUG_MODULE_INFORMATION(iBuf->ModuleInformation);
  dump_DEBUG_HEAP_INFORMATION(iBuf->HeapInformation);
  dump_DEBUG_LOCK_INFORMATION(iBuf->LockInformation);
}

PDEBUG_BUFFER WINAPI RtlCreateQueryDebugBuffer(IN ULONG iSize, IN BOOLEAN iEventPair) 
{
   PDEBUG_BUFFER oBuf = NULL;
   FIXME("(%d, %d): stub\n", iSize, iEventPair);
   if (iSize < sizeof(DEBUG_BUFFER)) {
     iSize = sizeof(DEBUG_BUFFER);
   }
   oBuf = (PDEBUG_BUFFER) RtlAllocateHeap(GetProcessHeap(), 0, iSize);
   memset(oBuf, 0, iSize);
   FIXME("(%d, %d): returning %p\n", iSize, iEventPair, oBuf);
   return oBuf;
}

NTSTATUS WINAPI RtlDestroyQueryDebugBuffer(IN PDEBUG_BUFFER iBuf) 
{
   NTSTATUS nts = STATUS_SUCCESS;
   FIXME("(%p): stub\n", iBuf);
   if (NULL != iBuf) {
     RtlFreeHeap(GetProcessHeap(), 0, iBuf->ModuleInformation);
     RtlFreeHeap(GetProcessHeap(), 0, iBuf->HeapInformation);
     RtlFreeHeap(GetProcessHeap(), 0, iBuf->LockInformation);
     RtlFreeHeap(GetProcessHeap(), 0, iBuf);
   }
   return nts;
}

NTSTATUS WINAPI RtlQueryProcessDebugInformation(IN ULONG iProcessId, IN ULONG iDebugInfoMask, IN OUT PDEBUG_BUFFER iBuf) 
{
   NTSTATUS nts = STATUS_SUCCESS;
   FIXME("(%d, %x, %p): stub\n", iProcessId, iDebugInfoMask, iBuf);
   iBuf->InfoClassMask = iDebugInfoMask;
   
   if (iDebugInfoMask & PDI_MODULES) {
     PDEBUG_MODULE_INFORMATION info = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(DEBUG_MODULE_INFORMATION));
     memset(info, 0, sizeof(DEBUG_MODULE_INFORMATION));
     iBuf->ModuleInformation = info;
   }
   if (iDebugInfoMask & PDI_HEAPS) {
     PDEBUG_HEAP_INFORMATION info = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(DEBUG_HEAP_INFORMATION));
     memset(info, 0, sizeof(DEBUG_HEAP_INFORMATION));
     if (iDebugInfoMask & PDI_HEAP_TAGS) {
     }
     if (iDebugInfoMask & PDI_HEAP_BLOCKS) {
     }
     iBuf->HeapInformation = info;
   }
   if (iDebugInfoMask & PDI_LOCKS) {
     PDEBUG_LOCK_INFORMATION info = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(DEBUG_LOCK_INFORMATION));
     memset(info, 0, sizeof(DEBUG_LOCK_INFORMATION));
     iBuf->LockInformation = info;
   }
   TRACE("returns:%p\n", iBuf);
   dump_DEBUG_BUFFER(iBuf);
   return nts;
}
