external/source/meterpreter/source/extensions/stdapi/server/fs/dir.c
DWORD request_fs_ls(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	LPCSTR directory;
	DWORD result = ERROR_SUCCESS;
	LPSTR expanded = NULL, tempFile = NULL;
	DWORD tempFileSize = 0;
	LPSTR baseDirectory = NULL;
	struct stat buf;

	directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);

	// Enumerate the directory if one was provided
	if (!directory)
		result = ERROR_INVALID_PARAMETER;
	else
	{
#ifdef _WIN32
		WIN32_FIND_DATA data;
		HANDLE ctx = NULL;
#else
		DIR *ctx;
		struct dirent *data;
#endif
		BOOLEAN freeDirectory = FALSE;
		LPSTR tempDirectory = (LPSTR)directory;

#ifdef _WIN32
		// If there is not wildcard mask on the directory, create a version of the
		// directory with a mask appended
		if (!strrchr(directory, '*'))
		{
			if (!(tempDirectory = (LPSTR)malloc(strlen(directory) + 3)))
			{
				result = ERROR_NOT_ENOUGH_MEMORY;
				goto out;
			}

			sprintf(tempDirectory, "%s\\*", directory);	

			// Dupe!
			if (!(baseDirectory = _strdup(directory)))
			{
				result = ERROR_NOT_ENOUGH_MEMORY;
				goto out;
			}
		}
		// Otherwise, if it does have an asterisk, we need to scan back and find
		// the base directory.  If there is no slash, it means we're listing the
		// cwd.
		else
		{
			PCHAR slash = strrchr(directory, '\\');

			if (slash)
			{
				*slash = 0;

				if (!(baseDirectory = _strdup(directory)))
				{
					result = ERROR_NOT_ENOUGH_MEMORY;
					goto out;
				}

				*slash = '\\';
			}
		}

		// Expand the path
		if (!(expanded = fs_expand_path(tempDirectory)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			goto out;
		}

		// Start the find operation
		ctx = FindFirstFile(expanded, &data);

 #define DF_NAME data.cFileName
#else
		expanded = 0;
		ctx = opendir(tempDirectory);
		if(ctx == NULL)
		{
		  result = errno;
		  goto out;
		}
		data = readdir(ctx);
	      
 #define DF_NAME data->d_name

#endif

		do
		{
			DWORD fullSize = (baseDirectory ? strlen(baseDirectory) : 0) + strlen(DF_NAME) + 2;

			// No context?  Sucktastic
			if (ctx == INVALID_HANDLE_VALUE)
			{
				result = GetLastError();
				break;
			}

			// Allocate temporary storage to stat the file
			if ((!tempFile) ||
			    (tempFileSize < fullSize))
			{
				if (tempFile)
					free(tempFile);

				// No memory means we suck a lot like spoon's mom
				if (!(tempFile = (LPSTR)malloc(fullSize)))
				{
					result = ERROR_NOT_ENOUGH_MEMORY;
					break;
				}

				// Update the tempFileSize so that we don't allocate if we don't
				// need to like a true efficient ninja
				tempFileSize = fullSize;
			}

			// Build the full path
			if (baseDirectory)
				sprintf(tempFile, "%s\\%s", baseDirectory, DF_NAME);
			else
				sprintf(tempFile, "%s", DF_NAME);

			// Add the file name to the response
			packet_add_tlv_string(response, TLV_TYPE_FILE_NAME, 
					DF_NAME);
			// Add the full path
			packet_add_tlv_string(response, TLV_TYPE_FILE_PATH,
					tempFile);

			// Stat the file to get more information about it.
			if (stat(tempFile, &buf) >= 0)
				packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf,
						sizeof(buf));

#ifdef _WIN32
		} while (FindNextFile(ctx, &data));
#else
	        } while (data = readdir(ctx));
#endif
#undef DF_NAME

		// Clean up resources
		if (freeDirectory)
			free(tempDirectory);
		if (ctx)
#ifdef _WIN32
			FindClose(ctx);
#else
			closedir(ctx);
#endif
	}

	if (expanded)
		free(expanded);

out:
	if (baseDirectory)
		free(baseDirectory);

	// Set the result and transmit the response
	packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);

	packet_transmit(remote, response, NULL);

	return ERROR_SUCCESS;
}
/*
 * Gets the contents of a given directory path and returns the list of file
 * names to the requestor.
 *
 * TLVs:
 *
 * req: TLV_TYPE_DIRECTORY_PATH - The directory that should be listed
 */
Gets the contents of a given directory path and returns the list of file
names to the requestor.



The directory that should be listed
Gets the contents of a given directory path and returns the list of file names to the requestor . The directory that should be listed
DWORD request_fs_ls(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	LPCSTR directory;
	DWORD result = ERROR_SUCCESS;
	LPSTR expanded = NULL, tempFile = NULL;
	DWORD tempFileSize = 0;
	LPSTR baseDirectory = NULL;
	struct stat buf;
	directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
	if (!directory)
		result = ERROR_INVALID_PARAMETER;
	else
	{
#ifdef _WIN32
		WIN32_FIND_DATA data;
		HANDLE ctx = NULL;
#else
		DIR *ctx;
		struct dirent *data;
#endif
		BOOLEAN freeDirectory = FALSE;
		LPSTR tempDirectory = (LPSTR)directory;
#ifdef _WIN32
		if (!strrchr(directory, '*'))
		{
			if (!(tempDirectory = (LPSTR)malloc(strlen(directory) + 3)))
			{
				result = ERROR_NOT_ENOUGH_MEMORY;
				goto out;
			}
			sprintf(tempDirectory, "%s\\*", directory);	
			if (!(baseDirectory = _strdup(directory)))
			{
				result = ERROR_NOT_ENOUGH_MEMORY;
				goto out;
			}
		}
		else
		{
			PCHAR slash = strrchr(directory, '\\');
			if (slash)
			{
				*slash = 0;
				if (!(baseDirectory = _strdup(directory)))
				{
					result = ERROR_NOT_ENOUGH_MEMORY;
					goto out;
				}
				*slash = '\\';
			}
		}
		if (!(expanded = fs_expand_path(tempDirectory)))
		{
			result = ERROR_NOT_ENOUGH_MEMORY;
			goto out;
		}
		ctx = FindFirstFile(expanded, &data);
 #define DF_NAME data.cFileName
#else
		expanded = 0;
		ctx = opendir(tempDirectory);
		if(ctx == NULL)
		{
		  result = errno;
		  goto out;
		}
		data = readdir(ctx);
 #define DF_NAME data->d_name
#endif
		do
		{
			DWORD fullSize = (baseDirectory ? strlen(baseDirectory) : 0) + strlen(DF_NAME) + 2;
			if (ctx == INVALID_HANDLE_VALUE)
			{
				result = GetLastError();
				break;
			}
			if ((!tempFile) ||
			    (tempFileSize < fullSize))
			{
				if (tempFile)
					free(tempFile);
				if (!(tempFile = (LPSTR)malloc(fullSize)))
				{
					result = ERROR_NOT_ENOUGH_MEMORY;
					break;
				}
				tempFileSize = fullSize;
			}
			if (baseDirectory)
				sprintf(tempFile, "%s\\%s", baseDirectory, DF_NAME);
			else
				sprintf(tempFile, "%s", DF_NAME);
			packet_add_tlv_string(response, TLV_TYPE_FILE_NAME, 
					DF_NAME);
			packet_add_tlv_string(response, TLV_TYPE_FILE_PATH,
					tempFile);
			if (stat(tempFile, &buf) >= 0)
				packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf,
						sizeof(buf));
#ifdef _WIN32
		} while (FindNextFile(ctx, &data));
#else
	        } while (data = readdir(ctx));
#endif
#undef DF_NAME
		if (freeDirectory)
			free(tempDirectory);
		if (ctx)
#ifdef _WIN32
			FindClose(ctx);
#else
			closedir(ctx);
#endif
	}
	if (expanded)
		free(expanded);
out:
	if (baseDirectory)
		free(baseDirectory);
	packet_add_tlv_uint(response, TLV_TYPE_RESULT, result);
	packet_transmit(remote, response, NULL);
	return ERROR_SUCCESS;
}
DWORD request_fs_ls ( Remote * remote , Packet * packet ) { Packet * response = packet_create_response ( packet ) ; LPCSTR directory ; DWORD result = ERROR_SUCCESS ; LPSTR expanded = NULL , tempFile = NULL ; DWORD tempFileSize = 0 ; LPSTR baseDirectory = NULL ; struct stat buf ; directory = packet_get_tlv_value_string ( packet , TLV_TYPE_DIRECTORY_PATH ) ; if ( ! directory ) result = ERROR_INVALID_PARAMETER ; else { #ifdef _WIN32 WIN32_FIND_DATA data ; HANDLE ctx = NULL ; #else DIR * ctx ; struct dirent * data ; #endif BOOLEAN freeDirectory = FALSE ; LPSTR tempDirectory = ( LPSTR ) directory ; #ifdef _WIN32 if ( ! strrchr ( directory , ' ' ) ) { if ( ! ( tempDirectory = ( LPSTR ) malloc ( strlen ( directory ) + 3 ) ) ) { result = ERROR_NOT_ENOUGH_MEMORY ; goto out ; } sprintf ( tempDirectory , " \\ " , directory ) ; if ( ! ( baseDirectory = _strdup ( directory ) ) ) { result = ERROR_NOT_ENOUGH_MEMORY ; goto out ; } } else { PCHAR slash = strrchr ( directory , ' \\ ' ) ; if ( slash ) { * slash = 0 ; if ( ! ( baseDirectory = _strdup ( directory ) ) ) { result = ERROR_NOT_ENOUGH_MEMORY ; goto out ; } * slash = ' \\ ' ; } } if ( ! ( expanded = fs_expand_path ( tempDirectory ) ) ) { result = ERROR_NOT_ENOUGH_MEMORY ; goto out ; } ctx = FindFirstFile ( expanded , & data ) ; #define DF_NAME  data.cFileName
 #else expanded = 0 ; ctx = opendir ( tempDirectory ) ; if ( ctx == NULL ) { result = errno ; goto out ; } data = readdir ( ctx ) ; #define DF_NAME  data->d_name
 #endif do { DWORD fullSize = ( baseDirectory ? strlen ( baseDirectory ) : 0 ) + strlen ( DF_NAME ) + 2 ; if ( ctx == INVALID_HANDLE_VALUE ) { result = GetLastError ( ) ; break ; } if ( ( ! tempFile ) || ( tempFileSize < fullSize ) ) { if ( tempFile ) free ( tempFile ) ; if ( ! ( tempFile = ( LPSTR ) malloc ( fullSize ) ) ) { result = ERROR_NOT_ENOUGH_MEMORY ; break ; } tempFileSize = fullSize ; } if ( baseDirectory ) sprintf ( tempFile , " \\ " , baseDirectory , DF_NAME ) ; else sprintf ( tempFile , " " , DF_NAME ) ; packet_add_tlv_string ( response , TLV_TYPE_FILE_NAME , DF_NAME ) ; packet_add_tlv_string ( response , TLV_TYPE_FILE_PATH , tempFile ) ; if ( stat ( tempFile , & buf ) >= 0 ) packet_add_tlv_raw ( response , TLV_TYPE_STAT_BUF , & buf , sizeof ( buf ) ) ; #ifdef _WIN32 } while ( FindNextFile ( ctx , & data ) ) ; #else 
	        } while (data = readdir(ctx));
 #endif #undef  DF_NAME
 if ( freeDirectory ) free ( tempDirectory ) ; if ( ctx ) #ifdef _WIN32 FindClose ( ctx ) ; #else closedir ( ctx ) ; #endif } if ( expanded ) free ( expanded ) ; out : if ( baseDirectory ) free ( baseDirectory ) ; packet_add_tlv_uint ( response , TLV_TYPE_RESULT , result ) ; packet_transmit ( remote , response , NULL ) ; return ERROR_SUCCESS ; }
Gets the contents of a given directory path and returns the list of file
 names to the requestor.
Gets the contents of a given directory path and returns the list of file names to the requestor .
// Enumerate the directory if one was provided
 // If there is not wildcard mask on the directory, create a version of the
 // directory with a mask appended
 // Dupe!
 // Otherwise, if it does have an asterisk, we need to scan back and find
 // the base directory.  If there is no slash, it means we're listing the
 // cwd.
 // Expand the path
 // Start the find operation
 // No context?  Sucktastic
 // Allocate temporary storage to stat the file
 // No memory means we suck a lot like spoon's mom
 // Update the tempFileSize so that we don't allocate if we don't
 // need to like a true efficient ninja
 // Build the full path
 // Add the file name to the response
 // Add the full path
 // Stat the file to get more information about it.
 // Clean up resources
 // Set the result and transmit the response
