Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F4823474
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
19 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c
index 130bfd8..e628c5c 100644
--- a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c
+++ b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c
@@ -1,391 +1,388 @@
/*******************************************************************************
* xmount Copyright (c) 2008-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* This module has been written by Guy Voncken. It contains the functions for *
* accessing dd images. Split dd is supported as well. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
-#include <string.h>
-#include <stddef.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <locale.h>
-#include <limits.h>
+#include <stdio.h>
+#include <string.h>
#include "../libxmount_input.h"
#include "libxmount_input_dd.h"
/*******************************************************************************
* LibXmount_Input API implementation
******************************************************************************/
/*
* LibXmount_Input_GetApiVersion
*/
uint8_t LibXmount_Input_GetApiVersion() {
return LIBXMOUNT_INPUT_API_VERSION;
}
/*
* LibXmount_Input_GetSupportedFormats
*/
const char* LibXmount_Input_GetSupportedFormats() {
return "dd\0\0";
}
/*
* LibXmount_Input_GetFunctions
*/
void LibXmount_Input_GetFunctions(ts_LibXmountInputFunctions *p_functions) {
p_functions->CreateHandle=&DdCreateHandle;
p_functions->DestroyHandle=&DdDestroyHandle;
p_functions->Open=&DdOpen;
p_functions->Close=&DdClose;
p_functions->Size=&DdSize;
p_functions->Read=&DdRead;
p_functions->OptionsHelp=&DdOptionsHelp;
p_functions->OptionsParse=&DdOptionsParse;
p_functions->GetInfofileContent=&DdGetInfofileContent;
p_functions->GetErrorMessage=&DdGetErrorMessage;
p_functions->FreeBuffer=&DdFreeBuffer;
}
/*******************************************************************************
* Private
******************************************************************************/
// ---------------------------
// Internal static functions
// ---------------------------
static inline uint64_t DdGetCurrentSeekPos (t_pPiece pPiece)
{
- return ftello (pPiece->pFile);
-}
-
-static inline int DdSetCurrentSeekPos (t_pPiece pPiece, uint64_t Val, int Whence)
-{
- if (fseeko (pPiece->pFile, Val, Whence) != 0)
- return DD_CANNOT_SEEK;
- return DD_OK;
-}
-
-static int DdDestroyHandle0 (t_pdd *ppdd)
-{
- t_pdd pdd = *ppdd;
- t_pPiece pPiece;
- int CloseErrors = 0;
-
- if (pdd->pPieceArr)
- {
- for (int i=0; i < pdd->Pieces; i++)
- {
- pPiece = &pdd->pPieceArr[i];
- if (pPiece->pFile)
- if (fclose (pPiece->pFile))
- CloseErrors++;
- if (pPiece->pFilename)
- free (pPiece->pFilename);
- }
- free (pdd->pPieceArr);
- }
- if (pdd->pInfo)
- free (pdd->pInfo);
-
- free (pdd);
- *ppdd = NULL;
-
- if (CloseErrors)
- return DD_CANNOT_CLOSE_FILE;
-
- return DD_OK;
+ return ftello (pPiece->pFile);
}
-static int DdCreateHandle0 (t_pdd pdd, unsigned FilenameArrLen, const char **ppFilenameArr)
+static inline int DdSetCurrentSeekPos (t_pPiece pPiece,
+ uint64_t Val,
+ int Whence)
{
- t_pPiece pPiece;
-
- pdd->Pieces = FilenameArrLen;
- pdd->pPieceArr = (t_pPiece) malloc (pdd->Pieces * sizeof(t_Piece));
- if (pdd->pPieceArr == NULL)
- {
- (void) DdDestroyHandle0 (&pdd);
- return DD_MEMALLOC_FAILED;
- }
-
- pdd->TotalSize = 0;
- for (int i=0; i < pdd->Pieces; i++)
- {
- pPiece = &pdd->pPieceArr[i];
- pPiece->pFilename = strdup (ppFilenameArr[i]);
- if (pPiece->pFilename == NULL)
- {
- (void) DdDestroyHandle0 (&pdd);
- return DD_MEMALLOC_FAILED;
- }
- pPiece->pFile = fopen (pPiece->pFilename, "r");
- if (pPiece->pFile == NULL)
- {
- (void) DdDestroyHandle0 (&pdd);
- return DD_FILE_OPEN_FAILED;
- }
- CHK(DdSetCurrentSeekPos(pPiece, 0, SEEK_END))
- pPiece->FileSize = DdGetCurrentSeekPos (pPiece);
- pdd->TotalSize += pPiece->FileSize;
- }
-
- asprintf (&pdd->pInfo, "dd image made of %u pieces, %llu bytes in total (%0.3f GiB)", pdd->Pieces, pdd->TotalSize, pdd->TotalSize / (1024.0*1024.0*1024.0));
-
- return DD_OK;
+ if (fseeko (pPiece->pFile, Val, Whence) != 0) return DD_CANNOT_SEEK;
+ return DD_OK;
}
static int DdRead0 (t_pdd pdd, uint64_t Seek, char *pBuffer, uint32_t *pCount)
{
- t_pPiece pPiece;
- int i;
+ t_pPiece pPiece;
+ uint64_t i;
- // Find correct piece to read from
- // -------------------------------
+ // Find correct piece to read from
+ // -------------------------------
- for (i=0; i<pdd->Pieces; i++)
- {
- pPiece = &pdd->pPieceArr[i];
- if (Seek < pPiece->FileSize)
- break;
- Seek -= pPiece->FileSize;
- }
- if (i >= pdd->Pieces)
- return DD_READ_BEYOND_END_OF_IMAGE;
+ for (i=0; i<pdd->Pieces; i++)
+ {
+ pPiece = &pdd->pPieceArr[i];
+ if (Seek < pPiece->FileSize) break;
+ Seek -= pPiece->FileSize;
+ }
+ if (i >= pdd->Pieces) return DD_READ_BEYOND_END_OF_IMAGE;
- // Read from this piece
- // --------------------
- CHK (DdSetCurrentSeekPos (pPiece, Seek, SEEK_SET))
+ // Read from this piece
+ // --------------------
+ CHK (DdSetCurrentSeekPos (pPiece, Seek, SEEK_SET))
- *pCount = GETMIN (*pCount, pPiece->FileSize - Seek);
+ *pCount = GETMIN (*pCount, pPiece->FileSize - Seek);
- if (fread (pBuffer, *pCount, 1, pPiece->pFile) != 1)
- return DD_CANNOT_READ_DATA;
+ if (fread (pBuffer, *pCount, 1, pPiece->pFile) != 1)
+ {
+ return DD_CANNOT_READ_DATA;
+ }
- return DD_OK;
+ return DD_OK;
}
// ---------------
// API functions
// ---------------
/*
* DdCreateHandle
*/
static int DdCreateHandle(void **pp_handle) {
t_pdd p_dd=(t_pdd)*pp_handle;
p_dd=(t_pdd)malloc(sizeof(t_dd));
if(p_dd==NULL) return DD_MEMALLOC_FAILED;
memset(p_dd,0,sizeof(t_dd));
return DD_OK;
}
/*
* DdDestroyHandle
*/
static int DdDestroyHandle(void **pp_handle) {
- // TODO: Implement
+ free(*pp_handle);
+ *pp_handle=NULL;
return DD_OK;
}
/*
* DdOpen
*/
static int DdOpen(void **pp_handle,
const char **pp_filename_arr,
uint64_t filename_arr_len)
{
- CHK(DdCreateHandle0((t_pdd)*pp_handle,filename_arr_len,pp_filename_arr))
+ t_pdd pdd=(t_pdd)*pp_handle;
+ t_pPiece pPiece;
+
+ pdd->Pieces = filename_arr_len;
+ pdd->pPieceArr = (t_pPiece) malloc (pdd->Pieces * sizeof(t_Piece));
+ if (pdd->pPieceArr == NULL) return DD_MEMALLOC_FAILED;
+ // Need to set everything to 0 in case an error occurs later and DdClose is
+ // called
+ memset(pdd->pPieceArr,0,pdd->Pieces * sizeof(t_Piece));
+
+ pdd->TotalSize = 0;
+ for (uint64_t i=0; i < pdd->Pieces; i++)
+ {
+ pPiece = &pdd->pPieceArr[i];
+ pPiece->pFilename = strdup (pp_filename_arr[i]);
+ if (pPiece->pFilename == NULL)
+ {
+ (void)DdClose(pp_handle);
+ return DD_MEMALLOC_FAILED;
+ }
+ pPiece->pFile = fopen (pPiece->pFilename, "r");
+ if (pPiece->pFile == NULL)
+ {
+ (void)DdClose(pp_handle);
+ return DD_FILE_OPEN_FAILED;
+ }
+ CHK(DdSetCurrentSeekPos(pPiece, 0, SEEK_END))
+ pPiece->FileSize = DdGetCurrentSeekPos (pPiece);
+ pdd->TotalSize += pPiece->FileSize;
+ }
+
return DD_OK;
}
/*
* DdClose
*/
static int DdClose(void **pp_handle) {
- CHK (DdDestroyHandle0((t_pdd*)pp_handle))
+ t_pdd pdd = (t_pdd)*pp_handle;
+ t_pPiece pPiece;
+ int CloseErrors = 0;
+
+ if (pdd->pPieceArr)
+ {
+ for (uint64_t i=0; i < pdd->Pieces; i++)
+ {
+ pPiece = &pdd->pPieceArr[i];
+ if (pPiece->pFile) {
+ if (fclose (pPiece->pFile)) CloseErrors=1;
+ }
+ if (pPiece->pFilename) free (pPiece->pFilename);
+ }
+ free (pdd->pPieceArr);
+ }
+
+ if (CloseErrors) return DD_CANNOT_CLOSE_FILE;
+
return DD_OK;
}
/*
* DdSize
*/
static int DdSize(void *p_handle, uint64_t *p_size) {
*p_size=((t_pdd)p_handle)->TotalSize;
return DD_OK;
}
/*
* DdRead
*/
static int DdRead(void *p_handle,
uint64_t seek,
char *p_buf,
uint32_t count)
{
uint32_t remaining=count;
uint32_t read;
if((seek+count)>((t_pdd)p_handle)->TotalSize) {
return DD_READ_BEYOND_END_OF_IMAGE;
}
do {
read=remaining;
CHK(DdRead0((t_pdd)p_handle,seek,p_buf,&read))
remaining-=read;
p_buf+=read;
seek+=read;
} while(remaining);
return DD_OK;
}
/*
* DdOptionsHelp
*/
static const char* DdOptionsHelp() {
return NULL;
}
/*
* DdOptionsParse
*/
static int DdOptionsParse(void *p_handle, char *p_options, char **pp_error) {
return DD_OK;
}
/*
* DdGetInfofileContent
*/
static int DdGetInfofileContent(void *p_handle, char **pp_info_buf) {
- // TODO: Rather then copying, generate info text once here. It won't be used
- // after this anymore.
- *pp_info_buf=(char*)malloc(strlen(((t_pdd)p_handle)->pInfo)+1);
- if(*pp_info_buf==NULL) {
- return DD_MEMALLOC_FAILED;
- }
-
- strcpy(*pp_info_buf,((t_pdd)p_handle)->pInfo);
+ asprintf(pp_info_buf,
+ "DD image assembled of %" PRIu64 " pieces\n"
+ "%" PRIu64 " bytes in total (%0.3f GiB)",
+ ((t_pdd)p_handle)->Pieces,
+ ((t_pdd)p_handle)->TotalSize,
+ ((t_pdd)p_handle)->TotalSize/(1024.0*1024.0*1024.0));
+ if(*pp_info_buf==NULL) return DD_MEMALLOC_FAILED;
return DD_OK;
}
/*
* DdGetErrorMessage
*/
static const char* DdGetErrorMessage(int err_num) {
- // TODO
- return "";
+ switch(err_num) {
+ case DD_MEMALLOC_FAILED:
+ return "Unable to allocate memory";
+ break;
+ case DD_FILE_OPEN_FAILED:
+ return "Unable to open DD file(s)";
+ break;
+ case DD_CANNOT_READ_DATA:
+ return "Unable to read DD data";
+ break;
+ case DD_CANNOT_CLOSE_FILE:
+ return "Unable to close DD file(s)";
+ break;
+ case DD_CANNOT_SEEK:
+ return "Unable to seek into DD data";
+ break;
+ case DD_READ_BEYOND_END_OF_IMAGE:
+ return "Unable to read DD data: Attempt to read past EOF";
+ break;
+ default:
+ return "Unknown error";
+ }
}
/*
* DdFreeBuffer
*/
static void DdFreeBuffer(void *p_buf) {
free(p_buf);
}
// -----------------------------------------------------
// Small main routine for testing
// It a split dd file to non-split dd
// -----------------------------------------------------
#ifdef DD_MAIN_FOR_TESTING
int main(int argc, const char *argv[])
{
t_pdd pdd;
uint64_t TotalSize;
uint64_t Remaining;
uint64_t Read;
uint64_t Pos;
uint32_t BuffSize = 1024;
char Buff[BuffSize];
FILE *pFile;
int Percent;
int PercentOld;
int rc;
printf ("Split DD to DD converter\n");
if (argc < 3)
{
printf ("Usage: %s <dd part 1> <dd part 2> <...> <dd destination>\n", argv[0]);
exit (1);
}
if (DdOpen ((void**)&pdd, argc-2, &argv[1]) != DD_OK)
{
printf ("Cannot open split dd file\n");
exit (1);
}
CHK (DdSize ((void*)pdd, &TotalSize))
printf ("Total size: %llu bytes\n", TotalSize);
Remaining = TotalSize;
pFile = fopen (argv[argc-1], "w");
if (pFile == NULL)
{
printf ("Cannot open destination file\n");
exit (1);
}
Remaining = TotalSize;
Pos = 0;
PercentOld = -1;
while (Remaining)
{
Read = GETMIN (Remaining, BuffSize);
rc = DdRead ((void*)pdd, Pos, &Buff[0], Read);
if (rc != DD_OK)
{
printf ("Error %d while calling DdRead\n", rc);
exit (1);
}
if (fwrite (Buff, Read, 1, pFile) != 1)
{
printf ("Could not write to destinationfile\n");
exit (2);
}
Remaining -= Read;
Pos += Read;
Percent = (100*Pos) / TotalSize;
if (Percent != PercentOld)
{
printf ("\r%d%% done...", Percent);
PercentOld = Percent;
}
}
if (fclose (pFile))
{
printf ("Error while closing destinationfile\n");
exit (3);
}
printf ("\n");
return 0;
}
#endif // DD_MAIN_FOR_TESTING
diff --git a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h
index ed45c6b..a17de44 100644
--- a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h
+++ b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h
@@ -1,120 +1,114 @@
/*******************************************************************************
* xmount Copyright (c) 2008-2013 by Gillen Daniel <gillen.dan@pinguin.lu> *
* *
* This module has been written by Guy Voncken. It contains the functions for *
* accessing dd images. Split dd is supported as well. *
* *
* xmount is a small tool to "fuse mount" various harddisk image formats as dd, *
* vdi, vhd or vmdk files and enable virtual write access to them. *
* *
* This program is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by the Free *
* Software Foundation, either version 3 of the License, or (at your option) *
* any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for *
* more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************/
#ifndef LIBXMOUNT_INPUT_DD_H
#define LIBXMOUNT_INPUT_DD_H
/*******************************************************************************
- * Error codes
+ * Error codes etc...
******************************************************************************/
-enum
-{
- DD_OK = 0,
- DD_FOUND,
-
- DD_MEMALLOC_FAILED=100,
- DD_FILE_OPEN_FAILED,
- DD_CANNOT_READ_DATA,
- DD_CANNOT_CLOSE_FILE,
- DD_CANNOT_SEEK,
- DD_READ_BEYOND_END_OF_IMAGE
+enum {
+ DD_OK=0,
+ DD_MEMALLOC_FAILED,
+ DD_FILE_OPEN_FAILED,
+ DD_CANNOT_READ_DATA,
+ DD_CANNOT_CLOSE_FILE,
+ DD_CANNOT_SEEK,
+ DD_READ_BEYOND_END_OF_IMAGE
};
// ----------------------
// Constant definitions
// ----------------------
#define GETMAX(a,b) ((a)>(b)?(a):(b))
#define GETMIN(a,b) ((a)<(b)?(a):(b))
-
// ---------------------
// Types and strutures
// ---------------------
-typedef struct {
- char *pFilename;
- unsigned long long FileSize;
- FILE *pFile;
+typedef struct {
+ char *pFilename;
+ uint64_t FileSize;
+ FILE *pFile;
} t_Piece, *t_pPiece;
-typedef struct _t_dd {
- t_pPiece pPieceArr;
- unsigned int Pieces;
- unsigned long long TotalSize;
- char *pInfo;
+typedef struct {
+ t_pPiece pPieceArr;
+ uint64_t Pieces;
+ uint64_t TotalSize;
} t_dd, *t_pdd;
-
// ----------------
// Error handling
// ----------------
#ifdef DD_DEBUG
#define CHK(ChkVal) \
{ \
int ChkValRc; \
if ((ChkValRc=(ChkVal)) != DD_OK) \
{ \
printf ("Err %d in %s, %d\n", ChkValRc, __FILE__, __LINE__); \
return ChkValRc; \
} \
}
#define DEBUG_PRINTF(pFormat, ...) \
printf (pFormat, ##__VA_ARGS__);
#else
#define CHK(ChkVal) \
{ \
int ChkValRc; \
if ((ChkValRc=(ChkVal)) != DD_OK) \
return ChkValRc; \
}
#define DEBUG_PRINTF(...)
#endif
/*******************************************************************************
* Forward declarations
******************************************************************************/
static int DdCreateHandle(void **pp_handle);
static int DdDestroyHandle(void **pp_handle);
static int DdOpen(void **pp_handle,
const char **pp_filename_arr,
uint64_t filename_arr_len);
static int DdClose(void **pp_handle);
static int DdSize(void *p_handle,
uint64_t *p_size);
static int DdRead(void *p_handle,
uint64_t seek,
char *p_buf,
uint32_t count);
static const char* DdOptionsHelp();
static int DdOptionsParse(void *p_handle,
char *p_options,
char **pp_error);
static int DdGetInfofileContent(void *p_handle,
char **pp_info_buf);
static const char* DdGetErrorMessage(int err_num);
static void DdFreeBuffer(void *p_buf);
#endif // LIBXMOUNT_INPUT_DD_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, May 11, 3:29 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1247601
Default Alt Text
(19 KB)
Attached To
Mode
rXMOUNT xmount
Attached
Detach File
Event Timeline
Log In to Comment