enable SMB on GameCube (thanks Extrems!)

This commit is contained in:
dborth 2011-02-03 03:10:06 +00:00
parent c3caf0a99d
commit c81d777705
5 changed files with 4388 additions and 4408 deletions

View File

@ -38,7 +38,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project # any extra libraries we wish to link with the project
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
LIBS := -lpng -lmxml -lfat -liso9660 -lz -logc -lfreetype LIBS := -lpng -lmxml -ltinysmb -lbba -lfat -liso9660 -lz -logc -lfreetype
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing # list of directories containing libraries, this must be the top level containing

View File

@ -571,15 +571,6 @@ int BrowserChangeFolder()
browserList[i].isdir = 1; browserList[i].isdir = 1;
browserList[i].icon = ICON_USB; browserList[i].icon = ICON_USB;
i++; i++;
AddBrowserEntry();
sprintf(browserList[i].filename, "smb:/");
sprintf(browserList[i].displayname, "Network Share");
browserList[i].length = 0;
browserList[i].mtime = 0;
browserList[i].isdir = 1;
browserList[i].icon = ICON_SMB;
i++;
#else #else
AddBrowserEntry(); AddBrowserEntry();
sprintf(browserList[i].filename, "carda:/"); sprintf(browserList[i].filename, "carda:/");
@ -599,6 +590,15 @@ int BrowserChangeFolder()
browserList[i].icon = ICON_SD; browserList[i].icon = ICON_SD;
i++; i++;
#endif #endif
AddBrowserEntry();
sprintf(browserList[i].filename, "smb:/");
sprintf(browserList[i].displayname, "Network Share");
browserList[i].length = 0;
browserList[i].mtime = 0;
browserList[i].isdir = 1;
browserList[i].icon = ICON_SMB;
i++;
AddBrowserEntry(); AddBrowserEntry();
sprintf(browserList[i].filename, "dvd:/"); sprintf(browserList[i].filename, "dvd:/");
sprintf(browserList[i].displayname, "Data DVD"); sprintf(browserList[i].displayname, "Data DVD");

View File

@ -413,11 +413,9 @@ bool ChangeInterface(int device, bool silent)
case DEVICE_DVD: case DEVICE_DVD:
mounted = MountDVD(silent); mounted = MountDVD(silent);
break; break;
#ifdef HW_RVL
case DEVICE_SMB: case DEVICE_SMB:
mounted = ConnectShare(silent); mounted = ConnectShare(silent);
break; break;
#endif
} }
return mounted; return mounted;

File diff suppressed because it is too large Load Diff

View File

@ -1,381 +1,375 @@
/**************************************************************************** /****************************************************************************
* FCE Ultra * FCE Ultra
* Nintendo Wii/Gamecube Port * Nintendo Wii/Gamecube Port
* *
* Tantric December 2008 * Tantric December 2008
* *
* networkop.cpp * networkop.cpp
* *
* Network and SMB support routines * Network and SMB support routines
****************************************************************************/ ****************************************************************************/
#ifdef HW_DOL #include <gccore.h>
#include <network.h>
bool #include <malloc.h>
ConnectShare (bool silent) #include <ogc/lwp_watchdog.h>
{ #include <smb.h>
return false; #include <mxml.h>
}
#include "fceugx.h"
#else #include "menu.h"
#include "fileop.h"
#include <gccore.h> #include "filebrowser.h"
#include <network.h> #include "utils/http.h"
#include <malloc.h> #include "utils/unzip/unzip.h"
#include <ogc/lwp_watchdog.h> #include "utils/unzip/miniunz.h"
#include <smb.h>
#include <mxml.h> static int netHalt = 0;
static bool networkInit = false;
#include "fceugx.h" static bool networkShareInit = false;
#include "menu.h" char wiiIP[16] = { 0 };
#include "fileop.h" static bool updateChecked = false; // true if checked for app update
#include "filebrowser.h" static char updateURL[128]; // URL of app update
#include "utils/http.h" bool updateFound = false; // true if an app update was found
#include "utils/unzip/unzip.h"
#include "utils/unzip/miniunz.h" #ifdef HW_RVL
static int netHalt = 0; /****************************************************************************
static bool networkInit = false; * UpdateCheck
static bool networkShareInit = false; * Checks for an update for the application
char wiiIP[16] = { 0 }; ***************************************************************************/
static bool updateChecked = false; // true if checked for app update
static char updateURL[128]; // URL of app update void UpdateCheck()
bool updateFound = false; // true if an app update was found {
// we only check for an update if we have internet + SD/USB
/**************************************************************************** if(updateChecked || !networkInit)
* UpdateCheck return;
* Checks for an update for the application
***************************************************************************/ if(!isMounted[DEVICE_SD] && !isMounted[DEVICE_USB])
return;
void UpdateCheck()
{ updateChecked = true;
// we only check for an update if we have internet + SD/USB u8 tmpbuffer[256];
if(updateChecked || !networkInit)
return; if (http_request("http://fceugc.googlecode.com/svn/trunk/update.xml", NULL, tmpbuffer, 256, SILENT) <= 0)
return;
if(!isMounted[DEVICE_SD] && !isMounted[DEVICE_USB])
return; mxml_node_t *xml;
mxml_node_t *item;
updateChecked = true;
u8 tmpbuffer[256]; xml = mxmlLoadString(NULL, (char *)tmpbuffer, MXML_TEXT_CALLBACK);
if (http_request("http://fceugc.googlecode.com/svn/trunk/update.xml", NULL, tmpbuffer, 256, SILENT) <= 0) if(!xml)
return; return;
mxml_node_t *xml; // check settings version
mxml_node_t *item; item = mxmlFindElement(xml, xml, "app", "version", NULL, MXML_DESCEND);
if(item) // a version entry exists
xml = mxmlLoadString(NULL, (char *)tmpbuffer, MXML_TEXT_CALLBACK); {
const char * version = mxmlElementGetAttr(item, "version");
if(!xml)
return; if(version && strlen(version) == 5)
{
// check settings version int verMajor = version[0] - '0';
item = mxmlFindElement(xml, xml, "app", "version", NULL, MXML_DESCEND); int verMinor = version[2] - '0';
if(item) // a version entry exists int verPoint = version[4] - '0';
{ int curMajor = APPVERSION[0] - '0';
const char * version = mxmlElementGetAttr(item, "version"); int curMinor = APPVERSION[2] - '0';
int curPoint = APPVERSION[4] - '0';
if(version && strlen(version) == 5)
{ // check that the versioning is valid and is a newer version
int verMajor = version[0] - '0'; if((verMajor >= 0 && verMajor <= 9 &&
int verMinor = version[2] - '0'; verMinor >= 0 && verMinor <= 9 &&
int verPoint = version[4] - '0'; verPoint >= 0 && verPoint <= 9) &&
int curMajor = APPVERSION[0] - '0'; (verMajor > curMajor ||
int curMinor = APPVERSION[2] - '0'; (verMajor == curMajor && verMinor > curMinor) ||
int curPoint = APPVERSION[4] - '0'; (verMajor == curMajor && verMinor == curMinor && verPoint > curPoint)))
{
// check that the versioning is valid and is a newer version item = mxmlFindElement(xml, xml, "file", NULL, NULL, MXML_DESCEND);
if((verMajor >= 0 && verMajor <= 9 && if(item)
verMinor >= 0 && verMinor <= 9 && {
verPoint >= 0 && verPoint <= 9) && const char * tmp = mxmlElementGetAttr(item, "url");
(verMajor > curMajor || if(tmp)
(verMajor == curMajor && verMinor > curMinor) || {
(verMajor == curMajor && verMinor == curMinor && verPoint > curPoint))) snprintf(updateURL, 128, "%s", tmp);
{ updateFound = true;
item = mxmlFindElement(xml, xml, "file", NULL, NULL, MXML_DESCEND); }
if(item) }
{ }
const char * tmp = mxmlElementGetAttr(item, "url"); }
if(tmp) }
{ mxmlDelete(xml);
snprintf(updateURL, 128, "%s", tmp); }
updateFound = true;
} static bool unzipArchive(char * zipfilepath, char * unzipfolderpath)
} {
} unzFile uf = unzOpen(zipfilepath);
} if (uf==NULL)
} return false;
mxmlDelete(xml);
} if(chdir(unzipfolderpath)) // can't access dir
{
static bool unzipArchive(char * zipfilepath, char * unzipfolderpath) makedir(unzipfolderpath); // attempt to make dir
{ if(chdir(unzipfolderpath)) // still can't access dir
unzFile uf = unzOpen(zipfilepath); return false;
if (uf==NULL) }
return false;
extractZip(uf,0,1,0);
if(chdir(unzipfolderpath)) // can't access dir
{ unzCloseCurrentFile(uf);
makedir(unzipfolderpath); // attempt to make dir return true;
if(chdir(unzipfolderpath)) // still can't access dir }
return false;
} bool DownloadUpdate()
{
extractZip(uf,0,1,0); bool result = false;
unzCloseCurrentFile(uf); if(updateURL[0] == 0 || appPath[0] == 0 || !ChangeInterface(appPath, NOTSILENT))
return true; {
} ErrorPrompt("Update failed!");
updateFound = false; // updating is finished (successful or not!)
bool DownloadUpdate() return false;
{ }
bool result = false;
// stop checking if devices were removed/inserted
if(updateURL[0] == 0 || appPath[0] == 0 || !ChangeInterface(appPath, NOTSILENT)) // since we're saving a file
{ HaltDeviceThread();
ErrorPrompt("Update failed!");
updateFound = false; // updating is finished (successful or not!) int device;
return false; FindDevice(appPath, &device);
}
char updateFile[50];
// stop checking if devices were removed/inserted sprintf(updateFile, "%s%s Update.zip", pathPrefix[device], APPNAME);
// since we're saving a file
HaltDeviceThread(); FILE * hfile = fopen (updateFile, "wb");
int device; if (hfile)
FindDevice(appPath, &device); {
if(http_request(updateURL, hfile, NULL, (1024*1024*10), NOTSILENT) > 0)
char updateFile[50]; {
sprintf(updateFile, "%s%s Update.zip", pathPrefix[device], APPNAME); fclose (hfile);
result = unzipArchive(updateFile, (char *)pathPrefix[device]);
FILE * hfile = fopen (updateFile, "wb"); }
else
if (hfile) {
{ fclose (hfile);
if(http_request(updateURL, hfile, NULL, (1024*1024*10), NOTSILENT) > 0) }
{ remove(updateFile); // delete update file
fclose (hfile); }
result = unzipArchive(updateFile, (char *)pathPrefix[device]);
} // go back to checking if devices were inserted/removed
else ResumeDeviceThread();
{
fclose (hfile); if(result)
} InfoPrompt("Update successful!");
remove(updateFile); // delete update file else
} ErrorPrompt("Update failed!");
// go back to checking if devices were inserted/removed updateFound = false; // updating is finished (successful or not!)
ResumeDeviceThread(); return result;
}
if(result)
InfoPrompt("Update successful!"); /****************************************************************************
else * InitializeNetwork
ErrorPrompt("Update failed!"); * Initializes the Wii/GameCube network interface
***************************************************************************/
updateFound = false; // updating is finished (successful or not!)
return result; static lwp_t networkthread = LWP_THREAD_NULL;
} static u8 netstack[8192] ATTRIBUTE_ALIGN (32);
/**************************************************************************** static void * netcb (void *arg)
* InitializeNetwork {
* Initializes the Wii/GameCube network interface s32 res;
***************************************************************************/ int retry;
int wait;
static lwp_t networkthread = LWP_THREAD_NULL;
static u8 netstack[8192] ATTRIBUTE_ALIGN (32); while(netHalt != 2)
{
static void * netcb (void *arg) retry = 30;
{
s32 res; while (retry)
int retry; {
int wait; net_deinit();
res = net_init_async(NULL, NULL);
while(netHalt != 2)
{ if(res != 0)
retry = 30; break; // failed
while (retry) res = net_get_status();
{ wait = 500; // only wait 10 sec
net_deinit(); while (res == -EBUSY && wait > 0)
res = net_init_async(NULL, NULL); {
usleep(20000);
if(res != 0) res = net_get_status();
break; // failed wait--;
}
res = net_get_status();
wait = 500; // only wait 10 sec if (res != -EAGAIN && res != -ETIMEDOUT)
while (res == -EBUSY && wait > 0) break;
{
usleep(20000); retry--;
res = net_get_status(); usleep(2000);
wait--; continue;
} }
if (res != -EAGAIN && res != -ETIMEDOUT) if (res == 0)
break; {
struct in_addr hostip;
retry--; hostip.s_addr = net_gethostip();
usleep(2000); if (hostip.s_addr)
continue; {
} strcpy(wiiIP, inet_ntoa(hostip));
networkInit = true;
if (res == 0) }
{ }
struct in_addr hostip; LWP_SuspendThread(networkthread);
hostip.s_addr = net_gethostip(); }
if (hostip.s_addr) return NULL;
{ }
strcpy(wiiIP, inet_ntoa(hostip));
networkInit = true; /****************************************************************************
} * StartNetworkThread
} *
LWP_SuspendThread(networkthread); * Signals the network thread to resume, or creates a new thread
} ***************************************************************************/
return NULL; void StartNetworkThread()
} {
netHalt = 0;
/****************************************************************************
* StartNetworkThread if(networkthread == LWP_THREAD_NULL)
* LWP_CreateThread(&networkthread, netcb, NULL, netstack, 8192, 40);
* Signals the network thread to resume, or creates a new thread else
***************************************************************************/ LWP_ResumeThread(networkthread);
void StartNetworkThread() }
{
netHalt = 0; /****************************************************************************
* StopNetworkThread
if(networkthread == LWP_THREAD_NULL) *
LWP_CreateThread(&networkthread, netcb, NULL, netstack, 8192, 40); * Signals the network thread to stop
else ***************************************************************************/
LWP_ResumeThread(networkthread); void StopNetworkThread()
} {
if(networkthread == LWP_THREAD_NULL)
/**************************************************************************** return;
* StopNetworkThread
* netHalt = 2;
* Signals the network thread to stop
***************************************************************************/ if(LWP_ThreadIsSuspended(networkthread))
void StopNetworkThread() LWP_ResumeThread(networkthread);
{
if(networkthread == LWP_THREAD_NULL) // wait for thread to finish
return; LWP_JoinThread(networkthread, NULL);
networkthread = LWP_THREAD_NULL;
netHalt = 2; }
if(LWP_ThreadIsSuspended(networkthread)) #endif
LWP_ResumeThread(networkthread);
bool InitializeNetwork(bool silent)
// wait for thread to finish {
LWP_JoinThread(networkthread, NULL); if(networkInit)
networkthread = LWP_THREAD_NULL; {
} #ifdef HW_RVL
StopNetworkThread();
bool InitializeNetwork(bool silent) #endif
{ return true;
if(networkInit) }
{
StopNetworkThread(); if(silent)
return true; return false;
}
int retry = 1;
if(silent)
return false; while(retry)
{
int retry = 1; u64 start = gettime();
while(retry) ShowAction("Initializing network...");
{
u64 start = gettime(); #ifdef HW_RVL
StartNetworkThread();
ShowAction("Initializing network...");
StartNetworkThread(); while (!LWP_ThreadIsSuspended(networkthread))
{
while (!LWP_ThreadIsSuspended(networkthread)) usleep(50 * 1000);
{
usleep(50 * 1000); if(diff_sec(start, gettime()) > 10) // wait for 10 seconds max for net init
break;
if(diff_sec(start, gettime()) > 10) // wait for 10 seconds max for net init }
break; #else
} networkInit = !(if_config(wiiIP, NULL, NULL, true) < 0);
#endif
CancelAction();
CancelAction();
if(networkInit)
break; if(networkInit)
break;
retry = ErrorPromptRetry("Unable to initialize network!");
} retry = ErrorPromptRetry("Unable to initialize network!");
return networkInit; }
} return networkInit;
}
void CloseShare()
{ void CloseShare()
if(networkShareInit) {
smbClose("smb"); if(networkShareInit)
networkShareInit = false; smbClose("smb");
isMounted[DEVICE_SMB] = false; networkShareInit = false;
} isMounted[DEVICE_SMB] = false;
}
/****************************************************************************
* Mount SMB Share /****************************************************************************
****************************************************************************/ * Mount SMB Share
****************************************************************************/
bool
ConnectShare (bool silent) bool
{ ConnectShare (bool silent)
// Crashes or stalls system in GameCube mode - so disable {
#ifndef HW_RVL if(!InitializeNetwork(silent))
return false; return false;
#endif
if(networkShareInit)
if(!InitializeNetwork(silent)) return true;
return false;
int retry = 1;
if(networkShareInit) int chkS = (strlen(GCSettings.smbshare) > 0) ? 0:1;
return true; int chkI = (strlen(GCSettings.smbip) > 0) ? 0:1;
int retry = 1; // check that all parameters have been set
int chkS = (strlen(GCSettings.smbshare) > 0) ? 0:1; if(chkS + chkI > 0)
int chkI = (strlen(GCSettings.smbip) > 0) ? 0:1; {
if(!silent)
// check that all parameters have been set {
if(chkS + chkI > 0) char msg[50];
{ char msg2[100];
if(!silent) if(chkS + chkI > 1) // more than one thing is wrong
{ sprintf(msg, "Check settings.xml.");
char msg[50]; else if(chkS)
char msg2[100]; sprintf(msg, "Share name is blank.");
if(chkS + chkI > 1) // more than one thing is wrong else if(chkI)
sprintf(msg, "Check settings.xml."); sprintf(msg, "Share IP is blank.");
else if(chkS)
sprintf(msg, "Share name is blank."); sprintf(msg2, "Invalid network settings - %s", msg);
else if(chkI) ErrorPrompt(msg2);
sprintf(msg, "Share IP is blank."); }
return false;
sprintf(msg2, "Invalid network settings - %s", msg); }
ErrorPrompt(msg2);
} while(retry)
return false; {
} if(!silent)
ShowAction ("Connecting to network share...");
while(retry)
{ if(smbInit(GCSettings.smbuser, GCSettings.smbpwd, GCSettings.smbshare, GCSettings.smbip))
if(!silent) networkShareInit = true;
ShowAction ("Connecting to network share...");
if(networkShareInit || silent)
if(smbInit(GCSettings.smbuser, GCSettings.smbpwd, GCSettings.smbshare, GCSettings.smbip)) break;
networkShareInit = true;
retry = ErrorPromptRetry("Failed to connect to network share.");
if(networkShareInit || silent) }
break;
if(!silent)
retry = ErrorPromptRetry("Failed to connect to network share."); CancelAction();
}
return networkShareInit;
if(!silent) }
CancelAction();
return networkShareInit;
}
#endif