I'm trying to make a checkers game in DirectX, but everytime I quit the app, I get an access violation error(can't read a part of the memory)

Here's all the code:

Code:
#define WIN32_LEAN_AND_MEAN


#include <windows.h>
#include <windowsx.h>
#include "resource.h"
#define INITGUID
#include <ddraw.h>

#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// initializes a direct draw struct
#define DD_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }
#define SAFE_RELEASE(x) {if(x) {x->Release(); x = NULL;}}

// GLOBALS ////////////////////////////////////////////////
HWND      g_hWnd =  NULL; // globally track main window
HINSTANCE g_hInstance      = NULL; // globally track hinstance
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_COLORS 16
#define CLASS_NAME "Checkers"
#define WINDOW_NAME "Checkers"

//LPDIRECTDRAW          lpDD         = NULL;   // dd object
LPDIRECTDRAW7         lpDD7        = NULL;   // dd4 object
LPDIRECTDRAWSURFACE7  lpDDSPrimary = NULL;   // dd primary surface
LPDIRECTDRAWSURFACE7  lpDDSBack    = NULL;   // dd back surface
LPDIRECTDRAWSURFACE7  lpDDSTile[8][8];
LPDIRECTDRAWPALETTE   lpDDPal      = NULL;   // a pointer to the created dd palette
LPDIRECTDRAWCLIPPER   lpDDClipper  = NULL;   // dd clipper
PALETTEENTRY          palette[256];          // color palette
DDSURFACEDESC2        DDSD;                  // a direct draw surface description struct
DDSCAPS2              DDSCaps;               // a direct draw surface capabilities struct
HBITMAP hbRedTile, hbBlackTile, hbRedPiece, hbBlackPiece;

LPDIRECTDRAWSURFACE7 bitmap_surface(int nResId)
{
	HDC hdc;
	HBITMAP bit;
	LPDIRECTDRAWSURFACE7 surf;
	bit = LoadBitmap(g_hInstance, MAKEINTRESOURCE(nResId));
	if(!bit)
		return NULL;
	BITMAP bitmap;
	GetObject(bit, sizeof(BITMAP), &bitmap);
	int surf_w = bitmap.bmWidth;
	int surf_h = bitmap.bmHeight;
	HRESULT hRes;
	DDSURFACEDESC2 DDSD2;
	ZeroMemory(&DDSD2, sizeof(DDSD2));
	DDSD2.dwSize = sizeof(DDSURFACEDESC2);
	DDSD2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	DDSD2.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
	DDSD2.dwWidth = surf_w;
	DDSD2.dwHeight = surf_h;
	
	hRes = lpDD7->CreateSurface(&DDSD2, &surf, NULL);
	if(hRes != DD_OK) {
		DeleteObject(bit);
		return NULL;
	}
	else {
		surf->GetDC(&hdc);
		HDC bit_dc = CreateCompatibleDC(hdc);
		SelectObject(bit_dc, bit);
		BitBlt(hdc, 0, 0, surf_w, surf_h, bit_dc, 0, 0, SRCCOPY);
		surf->ReleaseDC(hdc);
		DeleteDC(bit_dc);
	}
	DeleteObject(bit);
	
	return(surf);
}
void LoadImages()
{
	
	int x, y;
	for(x = 0; x < 8; x++)
	{
		for(y = 0; y < 8; y++)
		{
			if(((x % 2) == 1) && ((y % 2) == 1))
			{
				lpDDSTile[x][y] = bitmap_surface(IDB_BLACKTILE);
			} else {
				lpDDSTile[x][y] = bitmap_surface(IDB_REDTILE);
			}
		}
	}
}

void DrawBoard()
{
	//80x60
	int x, y;
	int xpos = 0, ypos = 0;
	for(x = 0; x < 8; x++)
	{
		for(y = 0; y < 8; y++)
		{
			lpDDSBack->BltFast(xpos,ypos, lpDDSTile[x][y], NULL, DDBLTFAST_WAIT);
			ypos += 60;
		}
		xpos += 80;
	}
}
int InitGame()
{
	if (FAILED(DirectDrawCreateEx(NULL, (LPVOID*)&lpDD7, IID_IDirectDraw7, NULL)))
	{
		return(0);
	} 
	if(!(lpDD7->SetCooperativeLevel(g_hWnd, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE))) MessageBox(NULL, "SetCooperativeLevel", "", MB_OK);
	if(!(lpDD7->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_COLORS, 0, 0))) MessageBox(NULL, "SetDisplayMode", "", MB_OK);
	ZeroMemory(&DDSD, sizeof(DDSURFACEDESC2));
	DDSD.dwSize = sizeof(DDSURFACEDESC2);
	DDSD.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
	DDSD.dwBackBufferCount = 1;	
	if(!(lpDD7->CreateSurface(&DDSD, &lpDDSPrimary, NULL))) MessageBox(NULL, "CreateSurface", "", MB_OK);
	DDSCaps.dwCaps = DDSCAPS_BACKBUFFER;
	
	HRESULT hRes = lpDDSPrimary->GetAttachedSurface(&DDSCaps, &lpDDSBack);
	if(hRes != DD_OK)  return(0);
	
	return(1);
}

int EndGame()
{
	SAFE_RELEASE(lpDDSPrimary);
	SAFE_RELEASE(lpDDSBack);
	SAFE_RELEASE(lpDD7);
	int x, y;
	for(x = 0; x < 8; x++)
	{
		for(y = 0; y < 8; y++)
		{
			SAFE_RELEASE(lpDDSTile[x][y]);
		}
	}
	return(1);
}

int GameMain()
{
	if (KEYDOWN(VK_ESCAPE))
		SendMessage(g_hWnd,WM_CLOSE,0,0);
	return(1);
	
}

Code:
#include "checkers.h"


LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	MSG msg;
	WNDCLASSEX winclass;
	HWND hWnd;
	
	winclass.cbSize = sizeof(WNDCLASSEX);
	winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
	winclass.lpfnWndProc = WinProc;
	winclass.cbClsExtra = 0;
	winclass.cbWndExtra = 0;
	winclass.hInstance = hInstance;
	winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
	winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	winclass.lpszMenuName = NULL;
	winclass.lpszClassName = CLASS_NAME;
	
	if(!RegisterClassEx(&winclass))
		return(0);
	
	if(!(hWnd = CreateWindowEx(NULL, CLASS_NAME, WINDOW_NAME, WS_POPUP | WS_VISIBLE, 0,0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL)))
		return(0);
	g_hWnd = hWnd;
	g_hInstance = hInstance;
	InitGame();
	while(true)
	{
		if(PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		} 
		GameMain();
		
	}
	EndGame();
	
	return(msg.wParam);
	
}

LRESULT CALLBACK WinProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	
    switch (uMsg) 
    { 
	case WM_CREATE: 
		//InitGame();
		//MessageBox(NULL, "test", "test", MB_OK);
		return 0; 
		
        //case WM_PAINT: 
		//DrawBoard();
		//return 0; 
		
        //case WM_SIZE: 
		return 0; 
	case WM_LBUTTONDBLCLK:
		EndGame();
		PostQuitMessage(0);
		return(0);
		//case WM_LBUTTONDOWN:
		
		//	return(0);
	case WM_DESTROY: 
		//EndGame();
		PostQuitMessage(0);
		return 0; 
		
        // 
        // Process other messages. 
        // 
		
	default: 
		return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 
}
I think the problem is occuring in InitGame, because when it only contained the first 6 lines, it didn't do this.


Thanks,
-Dennis