// Simple.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <setupapi.h>

#include <iostream>
#include <string>

using namespace std;

string GetCurDir()
{
	TCHAR buffer[MAX_PATH+1];
	::GetCurrentDirectory(sizeof(buffer), buffer);
	return buffer;
}

UINT CALLBACK MyCallback(PVOID Context, UINT Notification,
		UINT_PTR Param1,
		UINT_PTR Param2)
{

	switch(Notification)
	{
	case SPFILENOTIFY_STARTQUEUE:
		cout << "Lancement du processus "
			    "de copie des fichiers" << endl;
		break;

	case SPFILENOTIFY_STARTCOPY:
		FILEPATHS* filepaths;
		filepaths = reinterpret_cast<FILEPATHS*>(Param1);
		cout << endl << "Copie de ";
		cout << filepaths->Source << endl;
		cout << "vers:" << endl;
		cout << filepaths->Target << " ...";
		break;

	case SPFILENOTIFY_ENDCOPY:
		cout << "termine" << endl;
		break;

	case SPFILENOTIFY_ENDQUEUE:
		cout << "Fin de la copie des fichiers" << endl;
		break;
	default:
		break;

	}
	return SetupDefaultQueueCallback(
		Context,
		Notification,
		Param1,
		Param2);
}

int main(int argc, char* argv[])
{
	HINF MyInf;
	HSPFILEQ MyQueue = NULL;
	PVOID Context;
	UINT ErrorLine;
	TCHAR buffer[MAX_PATH+1];
	
	string filename = GetCurDir();
	filename += "\\Programmez.inf";
 
	cout << endl << "installation de HelloProg" << endl;

	MyInf = ::SetupOpenInfFile(
      filename.c_str(),       
      NULL,          
      INF_STYLE_WIN4,
      &ErrorLine);
	
	if(MyInf == INVALID_HANDLE_VALUE)
	{
		cout << "Impossible d'ouvrir le fichier .INF" << endl;
		cin.get();
		return 1;
	}
	cout << "Lecture du fichier .INF" << endl;

	DWORD RequiredSize;
	::SetupGetTargetPath(MyInf,
			NULL,
			"Programmez.Files.App",
			buffer,
			sizeof(buffer),
			&RequiredSize);

	cout << "Les binaires de l'application seront installes en "
		 << buffer << endl;

	// Création de la queue
	MyQueue = SetupOpenFileQueue();
	// Mise en place de la fonction de rappel
	Context = ::SetupInitDefaultQueueCallback(NULL);
	
	// Mise en queue des fichiers à copier	
	::SetupInstallFilesFromInfSection(
		MyInf,
		NULL,
		MyQueue,
		"DefaultInstall",
		NULL,
		SP_COPY_NOSKIP|SP_COPY_NOBROWSE);
	
	// Ou bien
	/*
	::SetupInstallFromInfSection(
		NULL,
		MyInf,
		"DefaultInstall",
		SPINST_FILES,
		NULL,
		NULL,
		NULL,
		MyCallback,
		Context,
		NULL,
		NULL);
		*/

	// Ajout du fichier Readme.txt
	string sourcepath = GetCurDir();
	::SetupQueueCopy(
		MyQueue,
		sourcepath.c_str(),
		NULL,
		"ReadMe.txt",
		NULL,
		NULL,
		buffer,
		NULL,
		SP_COPY_NOSKIP|SP_COPY_NOBROWSE
		); 

	// Copie des fichiers
	::SetupCommitFileQueue (
		NULL,
		MyQueue,
		MyCallback,
		Context);
	
	// Menu démarrer
	::SetupInstallFromInfSection(
		NULL,
		MyInf,
		"DefaultInstall",
		SPINST_PROFILEITEMS,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL);

	// Mise à jour du registre.
	::SetupInstallFromInfSection(
		NULL,
		MyInf,
		"DefaultInstall",
		SPINST_REGISTRY,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL);

	::SetupTermDefaultQueueCallback(Context);
	::SetupCloseFileQueue(MyQueue);
	::SetupCloseInfFile(MyInf);
	cout << "Installation terminee" << endl;
	cout << "appuyez sur une touche" << endl;
	cin.get();
	return 0;
}
