//
// Copyright (c) 2002
// Ronald Kevin Burton
//
// Z poniższym kodem nie jest związana żadna gwarancja poprawności działania.
// Program został dołączony do książki ".NET CLR. Księga eksperta" w celu
// ilustracji koncepcji i zasad przedstawionych w tej książce. Program może być 
// używany na własne ryzyko.
//
// Przyznaje się prawo do użycia lub kopiowania tego oprogramowania do dowolnego celu
// bez konieczności ponoszenia żadnych opłat pod warunkiem, że powyższe uwagi zostaną 
// zachowane we wszystkich kopiach. Przyznaje się także prawo do modyfikacji kodu
// i dystrybucji zmodyfikowanego kodu pod warunkiem zachowania powyższych uwag
// oraz dołączenia informacji mówiącej o modyfikacji kodu.
//
// 
// AssemblyDoc.cpp : plik implementacji
//

#include "stdafx.h"
#include "MDI.h"
#include "AssemblyDoc.h"


// CAssemblyDoc

IMPLEMENT_DYNCREATE(CAssemblyDoc, CDocument)

CAssemblyDoc::CAssemblyDoc()
{
	m_pImport = NULL;
	m_pDisp = NULL;
	HRESULT hr = CoCreateInstance(CLSID_CorMetaDataDispenser, NULL, CLSCTX_INPROC_SERVER, 
                                  IID_IMetaDataDispenserEx, (void **) &m_pDisp);
	hFile = INVALID_HANDLE_VALUE;
	hFileMap = NULL;
	pData = NULL;
}

CAssemblyDoc::~CAssemblyDoc()
{
	if(m_pImport != NULL)
		m_pImport->Release();
	if(m_pDisp != NULL)
		m_pDisp->Release();
	m_pImport = NULL;
	m_pDisp = NULL;

	if(pData != NULL)
		UnmapViewOfFile(pData);
	pData = NULL;
	if(hFileMap != NULL)
		CloseHandle(hFileMap);
	hFileMap = NULL;
	if(hFile != INVALID_HANDLE_VALUE)
		CloseHandle(hFile);
	hFile = INVALID_HANDLE_VALUE;
}


BEGIN_MESSAGE_MAP(CAssemblyDoc, CDocument)
END_MESSAGE_MAP()


// Diagnostyka CAssemblyDoc

#ifdef _DEBUG
void CAssemblyDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CAssemblyDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// Serializacja CAssemblyDoc

void CAssemblyDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: dodanie kodu zapisującego
	}
	else
	{
		// TODO: dodanie kodu ładującego
	}
}


// Polecenia CAssemblyDoc

BOOL CAssemblyDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
    WCHAR szScope[1024];
	wcscpy(szScope, L"file:");
    wcscat(szScope, lpszPathName);

    // Próba otwarcia zakresu dla danego pliku.
    HRESULT hr = m_pDisp->OpenScope(szScope, 0, IID_IMetaDataImport, (IUnknown**)&m_pImport);

	m_sAssemblyPath = lpszPathName;

	hFile = CreateFile(lpszPathName,			// Ścieżka pliku.
		               GENERIC_READ,			// Żądany rodzaj dostępu.
					   FILE_SHARE_READ,			// Tryb udostępniania.
					   NULL,					// Atrybuty zabezpieczeń.
					   OPEN_EXISTING,			// Sposób tworzenia.
					   FILE_ATTRIBUTE_NORMAL,	// 
					   NULL);					//

	if(hFile == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	hFileMap = CreateFileMapping(hFile,			// Uchwyt pliku (z CreateFile).
	                             NULL,			// Atrybuty zabezpieczeń.
								 PAGE_READONLY,	// Atrybut ochrony.
								 0, 0,			// Wielkość.
								 NULL);			// Nazwa mapy.
	if(hFileMap == NULL)
	{
		return FALSE;
	}

	pData = (PBYTE)MapViewOfFile(hFileMap,		// File mapping object
		                         FILE_MAP_READ, // Desired access
								 0, 0, 0);		// Offset and size
	if(pData == NULL)
	{
		return FALSE;
	}

	return TRUE;
}
