//
// $Id: FileProbe.cpp,v 1.5 2006/10/31 15:17:42 bakerj Exp $
//
//****************************************************************************************//
// Copyright (c) 2006, The MITRE Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice, this list
//       of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this 
//       list of conditions and the following disclaimer in the documentation and/or other
//       materials provided with the distribution.
//     * Neither the name of The MITRE Corporation nor the names of its contributors may be
//       used to endorse or promote products derived from this software without specific 
//       prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//****************************************************************************************//

#include "FileProbe.h"

//****************************************************************************************//
//								FileProbe Class											  //	
//****************************************************************************************//
FileProbe* FileProbe::instance = NULL;

FileProbe::FileProbe() {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//	Note that this is a private constructor
	// -----------------------------------------------------------------------

}

FileProbe::~FileProbe() {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//	Do nothing for now
	// -----------------------------------------------------------------------

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Public Members  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
AbsProbe* FileProbe::Instance() {

	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//	Ensure that the FileProbe is a singleton.
	// -----------------------------------------------------------------------

	// Use lazy initialization
	if(instance == NULL) 
		instance = new FileProbe();

	return instance;	
}

ItemVector* FileProbe::CollectItems(Object* object) {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//	Get all the files on the system that match the pattern. 
	//
	// -----------------------------------------------------------------------

	ItemVector *collectedItems = new ItemVector();

	// get the path and file name
	ObjectEntity* path = object->GetElementByName("path");
	ObjectEntity* fileName = object->GetElementByName("filename");

	FileFinder fileFinder;
	StringPairVector* filePaths = fileFinder.SearchFiles(path, fileName, object->GetBehaviors());

	// Loop through all file paths deleting them as they are completed.
	while(filePaths->size() > 0) {
		StringPair* fp = filePaths->at(filePaths->size()-1);
		filePaths->pop_back();

		if(fp->second.compare("") == 0) {

			Item* item = this->CreateItem();
			item->SetStatus(OvalEnum::EXISTS_STATUS);
			item->AppendElement(new ItemEntity("path", fp->first, OvalEnum::STRING_TYPE, true, OvalEnum::EXISTS_STATUS));
			collectedItems->push_back(item);

		} else {
			Item* item = this->GetFileAttributes(fp->first, fp->second);
			if(item != NULL) {
				collectedItems->push_back(item);
			}
			item = NULL;
		}
		delete fp;
	}

	return collectedItems;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Private Members  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
Item* FileProbe::CreateItem() {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//  Return a new Item created for storing file information
	//
	// -----------------------------------------------------------------------

	Item* item = new Item(0, 
						"http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#windows", 
						"win-sc", 
						"http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#windows windows-system-characteristics-schema.xsd", 
						OvalEnum::ERROR_STATUS, 
						"file_item");

	return item;
}

Item* FileProbe::GetFileAttributes(string path, string fileName) {
	// -----------------------------------------------------------------------
	//
	//  ABSTRACT
	//
	//	Get all attributes for the file specified in fileIn..Return them in a 
	//	FileAttribute
	// -----------------------------------------------------------------------

	HANDLE hFile;
	DWORD res;
	char buf[512];

	Item *item = NULL;

	string filePath = path;
	if(path[path.length()-1] != Common::fileSeperator)
		filePath.append(1, Common::fileSeperator);

	if(fileName[0] != Common::fileSeperator) {
		filePath.append(fileName);
	} else {
		filePath.append(fileName.substr(1, fileName.length()-2));
	}


	try {

		//////////////////////////////////////////////////////
		//////////////////////  Owner  ///////////////////////
		//////////////////////////////////////////////////////

		// Get the handle of the object.
		//
		// SMC-AUDIT: ISSUE: should probably verify that this is a regular file before opening,
		// instead of a virtual memory file!
		//
		// ARB:
		
		hFile = CreateFile(filePath.c_str(),				// file name
							GENERIC_READ,				// access mode
							FILE_SHARE_READ,			// share mode
							NULL,						// SD
							OPEN_EXISTING,				// how to create
							FILE_ATTRIBUTE_NORMAL,		// file attributes
							NULL);						// handle to template file

		if (hFile == INVALID_HANDLE_VALUE) {

			DWORD errorNum = GetLastError();

			if(errorNum == ERROR_FILE_NOT_FOUND) {

				
				/*errorMessage.append("(FileProbe) The file '");
				errorMessage.append(filePath);
				errorMessage.append("' could not be found.");*/
				

			} else if(errorNum == ERROR_PATH_NOT_FOUND) {

				/*errorMessage.append("(FileProbe) The path '");
				errorMessage.append(path);
				errorMessage.append("' does not exist.");*/


			} else {
				char errorCodeBuffer[33];
				_ltoa(errorNum, errorCodeBuffer, 10);

				string errorMessage = "";
				errorMessage.append("(FileProbe) Unable to open a handle to the file: '");
				errorMessage.append(filePath);
				errorMessage.append("'.  Error Code - ");
				errorMessage.append(errorCodeBuffer);
				throw ProbeException(errorMessage);
			}
		}

		// add the path and file name
		item = this->CreateItem();
		item->SetStatus(OvalEnum::EXISTS_STATUS);
		item->AppendElement(new ItemEntity("path", path, OvalEnum::STRING_TYPE, true, OvalEnum::EXISTS_STATUS));
		item->AppendElement(new ItemEntity("filename", fileName, OvalEnum::STRING_TYPE, true, OvalEnum::EXISTS_STATUS));
		ItemEntity* owner = new ItemEntity("owner", "", OvalEnum::STRING_TYPE, false, OvalEnum::ERROR_STATUS);
		item->AppendElement(owner);

		try {

			PSID owner_sid;
			PSECURITY_DESCRIPTOR p_sd;

			// Get the owner SID of the file.
			res = GetSecurityInfo(hFile,						// handle to object
								  SE_FILE_OBJECT,				// object type
								  OWNER_SECURITY_INFORMATION,	// information type
								  &owner_sid,					// owner SID
								  NULL,							// primary group SID
								  NULL,							// DACL
								  NULL,							// SACL
								  &p_sd);						// SD

			if (res != ERROR_SUCCESS) {

				string errorMessage = "";
				errorMessage.append("(FileProbe) Unable to get the security descriptor for the file: '");
				errorMessage.append(filePath);
				errorMessage.append("'.");
				throw ProbeException(errorMessage, ERROR_NOTICE);
			}

			// First call to LookupAccountSid to get the buffer sizes.
			LPTSTR aname = NULL;
			LPTSTR dname = NULL;
			DWORD dwaname = 0;
			DWORD dwdname = 0;
			SID_NAME_USE eUse;

			res = LookupAccountSid(NULL,					// name of local or remote computer
								   owner_sid,				// security identifier
								   aname,					// account name buffer
								   (LPDWORD)&dwaname,		// size of account name buffer
								   dname,					// domain name
								   (LPDWORD)&dwdname,		// size of domain name buffer
								   &eUse);					// SID type

			// Reallocate memory for the buffers.
			aname = (LPTSTR) malloc(dwaname);
			if (aname == NULL) {

				string errorMessage = "";
				errorMessage.append("(FileProbe) Could not allocate space for the owner name for file: '");
				errorMessage.append(filePath);
				errorMessage.append("'.");
				throw ProbeException(errorMessage);
			}

			dname = (LPTSTR) malloc(dwdname);
			if (dname == NULL) {

				free(aname);

				string errorMessage = "";
				errorMessage.append("(FileProbe) Could not allocate space for the domain name for the file: '");
				errorMessage.append(filePath);
				errorMessage.append("'.");
				throw ProbeException(errorMessage);
			}

			// Second call to LookupAccountSid to get the account name.
			res = LookupAccountSid(NULL,					// name of local or remote computer
								   owner_sid,				// security identifier
								   aname,					// account name buffer
								   (LPDWORD)&dwaname,		// size of account name buffer
								   dname,					// domain name
								   (LPDWORD)&dwdname,		// size of domain name buffer
								   &eUse);					// SID type

			if (res == FALSE) {

				free(aname);
				free(dname);

				string errorMessage = "";
				errorMessage.append("(FileProbe) Unable to get the name of the account ");
				errorMessage.append("for this SID for the file: '");
				errorMessage.append(filePath);
				errorMessage.append("'.");
				throw ProbeException(errorMessage);
			}
			
			//	Set owner 
			owner->SetValue(aname);
			owner->SetStatus(OvalEnum::EXISTS_STATUS);
			free(aname);
			free(dname);

		} catch(ProbeException ex) {	
			item->AppendMessage(new OvalMessage("Message: " + ex.GetErrorMessage()));
			owner->SetValue("");
			owner->SetStatus(OvalEnum::ERROR_STATUS);

		} catch(...) {
			
			string errorMessage = "";
			errorMessage.append("(FileProbe) Unknown error attempting to get the owner of the file '");
			errorMessage.append(filePath);
			errorMessage.append("' ");
			item->AppendMessage(new OvalMessage(errorMessage));
			owner->SetValue("");
			owner->SetStatus(OvalEnum::ERROR_STATUS);
		}

		//////////////////////////////////////////////////////
		/////////////////////  FileSize  /////////////////////
		//////////////////////////////////////////////////////

		struct _stat statusBuffer;
		int result;
 
		// Get status information associated with the file.
		result = _stat(filePath.c_str(), &statusBuffer);
		if (result < 0) {
			string errorMessage = "";
			errorMessage.append("(FileProbe) Unable to get status information ");
			errorMessage.append("associated with the file: '");
			errorMessage.append(filePath);
			errorMessage.append("'.");
			
			item->AppendElement(new ItemEntity("size", "", OvalEnum::INTEGER_TYPE, false, OvalEnum::ERROR_STATUS));
			item->AppendElement(new ItemEntity("a_time", "", OvalEnum::INTEGER_TYPE, false, OvalEnum::ERROR_STATUS));
			item->AppendElement(new ItemEntity("c_time", "", OvalEnum::INTEGER_TYPE, false, OvalEnum::ERROR_STATUS));
			item->AppendElement(new ItemEntity("m_time", "", OvalEnum::INTEGER_TYPE, false, OvalEnum::ERROR_STATUS));
			item->AppendMessage(new OvalMessage(errorMessage));
			
		} else {

			// Add file size.
			ZeroMemory(buf, sizeof(buf));
			_snprintf(buf, sizeof(buf)-1, "%ld", statusBuffer.st_size);
			buf[sizeof(buf)-1] = '\0';
			item->AppendElement(new ItemEntity("size", buf, OvalEnum::INTEGER_TYPE, false, OvalEnum::EXISTS_STATUS));

			//////////////////////////////////////////////////////
			/////////////////////  Accessed  /////////////////////
			//////////////////////////////////////////////////////
			ItemEntity* aTime = new ItemEntity("a_time",  Common::ToString((long)statusBuffer.st_atime), OvalEnum::INTEGER_TYPE, false, OvalEnum::EXISTS_STATUS);
			item->AppendElement(aTime);
			// Strip trailing \n if found
			if(aTime->GetValue().find_last_of("\n") == aTime->GetValue().length()-1)
				aTime->SetValue(aTime->GetValue().substr(0, aTime->GetValue().length()-1));

			//////////////////////////////////////////////////////
			/////////////////////  Created  /////////////////////
			//////////////////////////////////////////////////////
			ItemEntity* cTime = new ItemEntity("c_time",  Common::ToString((long)statusBuffer.st_ctime), OvalEnum::INTEGER_TYPE, false, OvalEnum::EXISTS_STATUS);
			item->AppendElement(cTime);
			// Strip trailing \n if found
			if(cTime->GetValue().find_last_of("\n") == cTime->GetValue().length()-1)
				cTime->SetValue(cTime->GetValue().substr(0, cTime->GetValue().length()-1));

			//////////////////////////////////////////////////////
			/////////////////////  Modified  /////////////////////
			//////////////////////////////////////////////////////
			ItemEntity* mTime = new ItemEntity("m_time",  Common::ToString((long)statusBuffer.st_mtime), OvalEnum::INTEGER_TYPE, false, OvalEnum::EXISTS_STATUS);
			item->AppendElement(mTime);
			// Strip trailing \n if found
			if(mTime->GetValue().find_last_of("\n") == mTime->GetValue().length()-1)
				mTime->SetValue(cTime->GetValue().substr(0, mTime->GetValue().length()-1));

		}

		//////////////////////////////////////////////////////
		////////////////////  MSChecksum  ////////////////////
		//////////////////////////////////////////////////////

		DWORD headersum;  
		DWORD checksum;

		res = MapFileAndCheckSum(const_cast<char*>(filePath.c_str()), &headersum, &checksum);
		if (res != CHECKSUM_SUCCESS) {
			string errorMessage = "";
			errorMessage.append("(FileProbe) Unable to get ms_checksum information for the file: '");
			errorMessage.append(filePath);
			errorMessage.append("'");
			item->AppendElement(new ItemEntity("ms_checksum", "", OvalEnum::INTEGER_TYPE, false, OvalEnum::ERROR_STATUS));
			item->AppendMessage(new OvalMessage(errorMessage));

		} else {
			ZeroMemory(buf, sizeof(buf));
			_snprintf(buf, sizeof(buf)-1, "%d", checksum);
			buf[sizeof(buf)-1] = '\0';
			item->AppendElement(new ItemEntity("ms_checksum", buf, OvalEnum::INTEGER_TYPE, false, OvalEnum::EXISTS_STATUS));
		}

		//////////////////////////////////////////////////////
		////////////////////  FileVersion  ///////////////////
		//////////////////////////////////////////////////////
		ItemEntity* type = new ItemEntity("type", "", OvalEnum::STRING_TYPE, false, OvalEnum::ERROR_STATUS);
		ItemEntity* devClass = new ItemEntity("development_class", "", OvalEnum::STRING_TYPE, false, OvalEnum::ERROR_STATUS);
		ItemEntity* version = new ItemEntity("version", "", OvalEnum::VERSION_TYPE, false, OvalEnum::ERROR_STATUS);
		item->AppendElement(version);
		item->AppendElement(type);
		item->AppendElement(devClass);

		char ver1[16];
		char ver2[16];
		char ver3[16];
		char ver4[16];

		ZeroMemory(ver1, sizeof(ver1));
		ZeroMemory(ver2, sizeof(ver2));
		ZeroMemory(ver3, sizeof(ver3));
		ZeroMemory(ver4, sizeof(ver4));

		DWORD junk;
		DWORD versionsize;
		LPVOID versionbuf;

		// Get the required size of the version info buffer.
		versionsize = GetFileVersionInfoSize(filePath.c_str(), &junk);
		if (versionsize > 0) {

			versionbuf = (LPVOID)malloc(versionsize);
			if (GetFileVersionInfo(filePath.c_str(), 0, versionsize, versionbuf) == TRUE) {
				VS_FIXEDFILEINFO* pFFI = NULL;
				UINT vdatalen;

				//	Get The major, minor, private and build numbers for the file
				if (VerQueryValue(versionbuf, "\\", (void**)&pFFI, &vdatalen) == FALSE) {

					string errorMessage = "";
					errorMessage.append("(FileProbe) Unable to get version information for the file '");
					errorMessage.append(filePath);
					errorMessage.append("'");
					item->AppendMessage(new OvalMessage(errorMessage));

				} else if (pFFI == NULL) {

					string errorMessage = "";
					errorMessage.append("(FileProbe) No version information available for the file: '");
					errorMessage.append(filePath);
					errorMessage.append("'");
					version->SetStatus(OvalEnum::DOES_NOT_EXIST_STATUS);
					item->AppendMessage(new OvalMessage(errorMessage));

				} else {
					_snprintf(ver1, sizeof(ver1)-1, "%d", (HIWORD(pFFI->dwFileVersionMS)));
					_snprintf(ver2, sizeof(ver2)-1, "%d", (LOWORD(pFFI->dwFileVersionMS)));
					_snprintf(ver3, sizeof(ver3)-1, "%d", (HIWORD(pFFI->dwFileVersionLS)));
					_snprintf(ver4, sizeof(ver4)-1, "%d", (LOWORD(pFFI->dwFileVersionLS)));
					
					string versionStr = "";
					versionStr.append(ver1);
					versionStr.append(".");
					versionStr.append(ver2);
					versionStr.append(".");
					versionStr.append(ver3);
					versionStr.append(".");
					versionStr.append(ver4);
					version->SetValue(versionStr);
					version->SetStatus(OvalEnum::EXISTS_STATUS);
				}

				//////////////////////////////////////////////////////
				///////////////  DevelopementClass  //////////////////
				//////////////////////////////////////////////////////

				//	Get the language-code page and construct the string for file version request
				DWORD *lpTransArray;
				TCHAR szSubblock[80];
				TCHAR szSubblockHeader[25];
				int retVal = VerQueryValue(versionbuf,  
							  TEXT("\\VarFileInfo\\Translation"),
							  (LPVOID*)&lpTransArray,
							  &vdatalen);

				if(retVal != 0) {
					
					//	Convert the code page info into a zero-terminated
					//	string specifying which version-information value to retrieve
					_stprintf(szSubblockHeader, TEXT("\\StringFileInfo\\%04X%04X"), LOWORD(lpTransArray[0]), HIWORD(lpTransArray[0]));					
					_stprintf(szSubblock, TEXT("%s\\%s"), szSubblockHeader, TEXT("FileVersion"));

					//	Get the file's developement class
					LPTSTR lpszValue;
					retVal = VerQueryValue(versionbuf,
											szSubblock, 
											(LPVOID *)&lpszValue, 
											&vdatalen);
								  
					if(retVal != 0) {

						//	Check to see if the version string has a developement path string in it
						string verStr = lpszValue;
						REGEX verMatcher;
						if(verMatcher.IsMatch(".+\\([^\\)].+\\)", verStr.c_str())) {

							//	Parse the version string
							verStr = verStr.substr(verStr.find("(") + 1);
							devClass->SetValue(verStr.substr(0, verStr.find(".")));
							devClass->SetStatus(OvalEnum::EXISTS_STATUS);
							
						} else {
							
							devClass->SetStatus(OvalEnum::DOES_NOT_EXIST_STATUS);
						}

					} else if(vdatalen == 0) {

						string errorMessage = "";
						errorMessage.append("(FileProbe) Unable to get development_class. No value is available for the specified version-information name, \"szSubblock,\" for file: ");
						errorMessage.append(filePath);
						errorMessage.append("'");
						item->AppendMessage(new OvalMessage(errorMessage));
						devClass->SetStatus(OvalEnum::DOES_NOT_EXIST_STATUS);

					} else if(retVal == 0) {

						string errorMessage = "";
						errorMessage.append("(FileProbe) Unable to get development_class. Either specified name, \"szSubblock,\" does not exist or the specified resource is not valid for file: ");
						errorMessage.append(filePath);
						errorMessage.append("'");
						item->AppendMessage(new OvalMessage(errorMessage));
						devClass->SetStatus(OvalEnum::DOES_NOT_EXIST_STATUS);
					}

				} else if(vdatalen == 0) {

					string errorMessage = "";
					errorMessage.append("(FileProbe) Unable to get development_class. No value is available for the specified version-information name, \"szSubblock,\" for file: ");
					errorMessage.append(filePath);
					errorMessage.append("'");
					item->AppendMessage(new OvalMessage(errorMessage));
					devClass->SetStatus(OvalEnum::DOES_NOT_EXIST_STATUS);

				} else if(retVal == 0) {

					string errorMessage = "";
					errorMessage.append("(FileProbe) Unable to get development_class. Either specified name, \"szSubblock,\" does not exist or the specified resource is not valid for file: ");
					errorMessage.append(filePath);
					errorMessage.append("'");
					item->AppendMessage(new OvalMessage(errorMessage));
					devClass->SetStatus(OvalEnum::DOES_NOT_EXIST_STATUS);
				}

			} else {

				string errorMessage = "";
				errorMessage.append("(FileProbe) Unable to get development_class for the file: '");
				errorMessage.append(filePath);
				errorMessage.append("'");
				item->AppendMessage(new OvalMessage(errorMessage));
				devClass->SetStatus(OvalEnum::ERROR_STATUS);
			}

			free(versionbuf);

		} else {

			string errorMessage = "";
			errorMessage.append("(FileProbe) Unable to get development_class. No version information available for the file: '");
			errorMessage.append(filePath);
			errorMessage.append("'");
			item->AppendMessage(new OvalMessage(errorMessage));
			version->SetStatus(OvalEnum::ERROR_STATUS);
		}

		//////////////////////////////////////////////////////
		/////////////////////  FileType  /////////////////////
		//////////////////////////////////////////////////////

		res = GetFileType(hFile);

		BOOL gfaRes;
		WIN32_FILE_ATTRIBUTE_DATA lpFileInformation;

		switch (res) {

			case FILE_TYPE_DISK:

				gfaRes = GetFileAttributesEx(filePath.c_str(),				// file or directory name
											 GetFileExInfoStandard,			// attribute class
											 (LPVOID)&lpFileInformation);	// attribute information 

				if (lpFileInformation.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
					type->SetValue("FILE_ATTRIBUTE_DIRECTORY");
				else
						type->SetValue("FILE_TYPE_DISK");

				type->SetStatus(OvalEnum::EXISTS_STATUS);

				break;

			case FILE_TYPE_CHAR:

				type->SetValue("FILE_TYPE_CHAR");
				type->SetStatus(OvalEnum::EXISTS_STATUS);
				break;

			case FILE_TYPE_PIPE:

				type->SetValue("FILE_TYPE_PIPE");
				type->SetStatus(OvalEnum::EXISTS_STATUS);
				break;

			case FILE_TYPE_UNKNOWN:

				{
					string errorMessage = "";
					errorMessage.append("(FileProbe) No file type information available for the file: '");
					errorMessage.append(filePath);
					errorMessage.append("'");
					item->AppendMessage(new OvalMessage(errorMessage));
					type->SetStatus(OvalEnum::ERROR_STATUS);
				}
				
				break;

			default:

				{
					string errorMessage = "";
					errorMessage.append("(FileProbe) Unable to get file type information for the file: '");
					errorMessage.append(filePath);
					errorMessage.append("'");
					item->AppendMessage(new OvalMessage(errorMessage));
					type->SetStatus(OvalEnum::ERROR_STATUS);
				}
				
				break;
		}

		//////////////////////////////////////////////////////
		//////////////////////////////////////////////////////
	} catch(ProbeException ex) {	
	
		Log::Debug(ex.GetErrorMessage());

	} catch(...) {	
	
		string errMsg = "";
		errMsg.append("(FileProbe) Unknown error attempting to get file attribute information for the file: '");
		errMsg.append(filePath);
		errMsg.append("'");
		Log::Debug(errMsg);
		
	}

	return item;
}
