Skip to content

Commit

Permalink
Implement recognising an IM2 Maildir style message store
Browse files Browse the repository at this point in the history
  • Loading branch information
smowton committed Feb 9, 2016
1 parent 2b8faeb commit 68e5ab5
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 45 deletions.
4 changes: 4 additions & 0 deletions Source/increadimail_convert.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ typedef enum INCREDIMAIL_VERSIONS {
INCREDIMAIL_VERSION_UNKNOWN,
INCREDIMAIL_XE,
INCREDIMAIL_2,
INCREDIMAIL_2_MAILDIR // Some versions of IM2 use a maildir-like format instead of a .imm file (~mbox).
// This might depend on precise version of IM, Windows version or both.
};

extern HWND global_hwnd;
Expand Down Expand Up @@ -151,6 +153,8 @@ void Incredimail_2_Email_Count( char *filename, int *email_total, int *deleted_e
//
//***************************************************************************

void Incredimail_2_Maildir_Email_Count(char *filename, int *email_total, int *deleted_emails);

void Incredimail_2_Get_Email_Offset_and_Size( char *filename, unsigned int *file_offset, unsigned int *size, int email_index, int *deleted_email );
//***************************************************************************
// INPUTS:
Expand Down
133 changes: 111 additions & 22 deletions Source/incredimail_convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#include "sqlite3.h"
#include "increadimail_convert.h"
Expand Down Expand Up @@ -346,33 +347,121 @@ int total_count = 1;
return total_count;
}

enum INCREDIMAIL_VERSIONS FindIncredimailVersion( char *directory_search ) {
char temp_path[MAX_CHAR];
enum INCREDIMAIL_VERSIONS ret = INCREDIMAIL_VERSION_UNKNOWN;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
static int testimdb(const char* filename) {

// is there an Incredimail XE header file
strcpy( temp_path, directory_search );
strcat( temp_path, "\\*.imh");
hFind = FindFirstFile(temp_path, &FindFileData);
FindClose( hFind );
struct _stat statbuf;
sqlite3 *db;
sqlite3_stmt *stmt;
int ret = 0;

if( hFind != INVALID_HANDLE_VALUE ) {
ret = INCREDIMAIL_XE;
}
if (_stat(filename, &statbuf) != 0)
return 0;

// is there an Incredimail 2 database, i.e. containers.db
strcpy( temp_path, directory_search );
strcat( temp_path, "\\*.db");
hFind = FindFirstFile(temp_path, &FindFileData);
if (sqlite3_open_v2(filename, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK)
return 0;

if( hFind != INVALID_HANDLE_VALUE ) {
ret = INCREDIMAIL_2;
}
FindClose( hFind );
if (sqlite3_prepare_v2(db, "select count(*) from Containers", -1, &stmt, NULL) != SQLITE_OK)
goto outdb;

if (sqlite3_step(stmt) != SQLITE_ROW)
goto outstmt;

if (sqlite3_column_int(stmt, 0) == 0)
goto outstmt;

ret = 1;

outstmt:
sqlite3_reset(stmt);
sqlite3_finalize(stmt);

outdb:
sqlite3_close(db);

return ret;

}

enum INCREDIMAIL_VERSIONS FindIncredimailVersion(char *directory_search) {
char temp_path[MAX_CHAR];
enum INCREDIMAIL_VERSIONS ret = INCREDIMAIL_VERSION_UNKNOWN;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;

// is there an Incredimail XE header file
strcpy(temp_path, directory_search);
strcat(temp_path, "\\*.imh");
hFind = FindFirstFile(temp_path, &FindFileData);
FindClose(hFind);

if (hFind != INVALID_HANDLE_VALUE) {
ret = INCREDIMAIL_XE;
}

// is there an Incredimail 2 database, i.e. containers.db
strcpy(temp_path, directory_search);
strcat(temp_path, "\\containers.db");

if (testimdb(temp_path)) {
ret = INCREDIMAIL_2;
}
else {
// Is there a messageStore.db, indicating maildir format?
strcpy(temp_path, directory_search);
strcat(temp_path, "\\messageStore.db");
if (testimdb(temp_path))
ret = INCREDIMAIL_2_MAILDIR;
}

return ret;
}

void Incredimail_2_Maildir_Email_Count(char *filename, int *email_total, int *deleted_emails) {

sqlite3 *db;
sqlite3_stmt *stmt;

const char* allMailQuery = "select count(*) from Headers";
const char* notDeletedQuery = "select count(*) from Headers where deleted = 0";

*email_total = 0;
*deleted_emails = 0;

if (sqlite3_open(filename, &db) != SQLITE_OK) {
char msg[4096];
snprintf(msg, 4096, "Unable to open sqlite3 DB %s", filename);
MessageBox(global_hwnd, msg, "Error!", MB_OK);
return;
}

if (sqlite3_prepare_v2(db, allMailQuery, -1, &stmt, NULL) != SQLITE_OK)
goto outdb;

if (sqlite3_step(stmt) != SQLITE_ROW)
goto outstmt;

*email_total = sqlite3_column_int(stmt, 0);

sqlite3_reset(stmt);
sqlite3_finalize(stmt);

if (sqlite3_prepare_v2(db, notDeletedQuery, -1, &stmt, NULL) != SQLITE_OK)
goto outdb;

if (sqlite3_step(stmt) != SQLITE_ROW)
goto outstmt;

*deleted_emails = sqlite3_column_int(stmt, 0);

outstmt:

sqlite3_reset(stmt);
sqlite3_finalize(stmt);

outdb:

sqlite3_close(db);

return ret;
}

void Incredimail_2_Email_Count( char *filename, int *email_total, int *deleted_emails ) {
Expand Down
26 changes: 18 additions & 8 deletions Source/resource.rc
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
// English (United States) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -63,7 +61,7 @@ BEGIN
EDITTEXT IDC_EDIT1,15,22,258,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_BROWSE2,221,104,50,14
EDITTEXT IDC_EDIT2,15,86,255,14,ES_AUTOHSCROLL
CONTROL "",IDC_PROGRESS1,"msctls_progress32",WS_BORDER | 0x1,8,235,277,14
CONTROL "",IDC_PROGRESS1,"msctls_progress32",PBS_SMOOTH | WS_BORDER,8,235,277,14
LTEXT "Progress",IDC_STATIC,9,225,29,8
LTEXT "Email Count:",IDC_ECOUNT,12,194,106,8
RTEXT "",IDC_XOFX,197,225,88,8
Expand All @@ -80,8 +78,8 @@ BEGIN
CONTROL "Export a Single Database",IDC_EXPORT_FILE,"Button",BS_AUTORADIOBUTTON,16,43,97,10
CONTROL "Export a Complete Directory",IDC_EXPORT_DIRECTORY,
"Button",BS_AUTORADIOBUTTON,16,56,107,10
LTEXT "Database Name:",IDC_DATABASE_NAME,11,170,257,8
CONTROL "",IDC_PROGRESS2,"msctls_progress32",NOT WS_VISIBLE | WS_BORDER | 0x1,7,261,278,14
CONTROL "Database Name:",IDC_DATABASE_NAME,"Static",SS_LEFTNOWORDWRAP | SS_ENDELLIPSIS | WS_GROUP,11,170,257,8
CONTROL "",IDC_PROGRESS2,"msctls_progress32",PBS_SMOOTH | NOT WS_VISIBLE | WS_BORDER,7,261,278,14
LTEXT "Overall Progress",IDC_OVERALL_PROGRESS,8,251,54,8,NOT WS_VISIBLE
RTEXT "",IDC_OVERALL_PERCENT,205,251,79,8,NOT WS_VISIBLE
END
Expand All @@ -106,7 +104,7 @@ END
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
GUIDELINES DESIGNINFO
BEGIN
IDD_DIALOG1, DIALOG
BEGIN
Expand Down Expand Up @@ -135,7 +133,19 @@ END
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_REYNARD ICON "reynard.ico"
#endif // English (U.S.) resources


/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//

IDD_DIALOG1 AFX_DIALOG_LAYOUT
BEGIN
0
END

#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////


Expand Down
32 changes: 17 additions & 15 deletions Source/winmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ BOOL CALLBACK Winload( HWND hdwnd, UINT message, WPARAM wparam, LPARAM lparam )
// strings
char file_title[MAX_CHAR];
char window_title[MAX_CHAR];
char filter[MAX_CHAR];
char im_database_filename[MAX_CHAR];
char im_header_filename[MAX_CHAR];
char im_attachments_directory[MAX_CHAR];
Expand Down Expand Up @@ -238,46 +237,49 @@ HANDLE hFind;
} else {
ZeroMemory( &window_title, sizeof( window_title ) );
ZeroMemory( &openfile, sizeof( openfile ) );
ZeroMemory( &filter, sizeof( filter ) );
ZeroMemory( &version, sizeof( version ) );

openfile.hwndOwner = hdwnd;
openfile.lStructSize = sizeof( openfile );
openfile.Flags = OFN_READONLY;
openfile.nMaxFile = sizeof( im_database_filename );
openfile.lpstrFileTitle = file_title;
openfile.lpstrFile = &im_database_filename[0];
openfile.lpstrFile = im_database_filename;
openfile.nMaxFileTitle = sizeof( file_title );

strcpy_s( window_title, sizeof("Open Incredimail Database File"), "Open Incredimail Database File");
strcpy_s( window_title, sizeof(window_title), "Open Incredimail Database File");
openfile.lpstrTitle = window_title;

strcpy_s( filter, sizeof("Incredimail Database *.imm\0*.imm\0\0"), "Incredimail Database *.imm\0*.imm\0\0" );
openfile.lpstrFilter = &filter[0];

strcpy_s( im_database_filename, sizeof("*.imm"), "*.imm" );
const char* filter = "Incredimail Database\0*.imm;*.db\0";
openfile.lpstrFilter = filter;

if( GetOpenFileName( &openfile ) == TRUE ) {
SetDlgItemText( hdwnd, IDC_EDIT1, im_database_filename );

// get the directory (reuse varible im_header_filename)
strncpy_s( im_header_filename, MAX_CHAR , im_database_filename, strlen( im_database_filename ) - strlen( openfile.lpstrFileTitle ) );
if( FindIncredimailVersion( im_header_filename ) == INCREDIMAIL_XE ) {
enum INCREDIMAIL_VERSION version = FindIncredimailVersion(im_header_filename);
if(version == INCREDIMAIL_XE) {
strncpy_s( im_header_filename, MAX_CHAR ,im_database_filename, strlen( im_database_filename ) - 3 );
strcat_s( im_header_filename, MAX_CHAR, "imh" );
email_count( im_header_filename, &e_count, &d_count );
SetDlgItemText( hdwnd, IDC_STATIC6, "Version: Incredimail XE" );
} else {
Incredimail_2_Email_Count( im_database_filename, &e_count, &d_count );
} else if(version == INCREDIMAIL_2) {
Incredimail_2_Email_Count(im_database_filename, &e_count, &d_count);
SetDlgItemText( hdwnd, IDC_STATIC6, "Version: Incredimail 2" );
}
} else if (version == INCREDIMAIL_2_MAILDIR) {
Incredimail_2_Maildir_Email_Count(im_database_filename, &e_count, &d_count);
SetDlgItemText(hdwnd, IDC_STATIC6, "Version: Incredimail 2 Maildir");
} else {
SetDlgItemText(hdwnd, IDC_STATIC6, "No database found");
return 1;
}
sprintf_s( debug_str, MAX_CHAR, "Email Count: %d", e_count );
SetDlgItemText( hdwnd, IDC_ECOUNT, debug_str );
sprintf_s( debug_str, MAX_CHAR, "Deleted Emails: %d", d_count );
SetDlgItemText( hdwnd, IDC_STATIC8, debug_str );
sprintf_s( debug_str, MAX_CHAR, "Database Name: %s", im_database_filename );
SetDlgItemText( hdwnd, IDC_DATABASE_NAME, debug_str );

SetDlgItemText(hdwnd, IDC_EDIT1, im_database_filename);

// insert automatic attachment directory here
strncpy_s( im_database_filename, MAX_CHAR, openfile.lpstrFile, strlen(openfile.lpstrFile)-strlen(openfile.lpstrFileTitle) );
strcat_s( im_database_filename, MAX_CHAR, "Attachments");
Expand Down

0 comments on commit 68e5ab5

Please sign in to comment.