【求助】小弟新手,正拿MFC写MySQL数据库密码重置工具,但卡住了,不知道怎么写了,100块钱求助!

光-光 2011-10-24 10:00:58
首先问高们一个问题,不知道能不能实现?

比如我有一个变量

LPSTR lpCmd = "DOS命令";

LPCTSTR lpCmdFile = "C:\\WINDOWS\\system32\\cmd.exe";
ShellExecute(NULL, "open", lpCmdFile, NULL, NULL, SW_SHOW);

然后用Spy++查找窗口名称得到窗口句柄

WND CmdHwnd = ::FindWindow(NULL, "C:\WINDOWS\system32\cmd.exe");
::PostMessage(CmdHwnd, WM_SETTEXT, 0, (LPARAM)completeCommand);
::PostMessage(CmdHwnd, WM_KEYDOWN, 13, 0);

我这么做不行,请高手指导,谢谢!

我MySQL数据库密码重置主要代码在这。

声明
public:
  //对比两次密码输入是否相同
  BOOL CheckPassword();
  //得到MySQL数据库安装路径
  BOOL GetMysqlPath(LPSTR lpMysql);
  //提升进程操作权限
  BOOL ElevatedPermissions();
  //强制结束应用程序进程
  BOOL KillProcess(LPCSTR lpProcessName);
  //跳过MySQL数据库安全验证
  BOOL SkipMysqlVerification(LPSTR lpMysqld, char completePath[]);
  //进入MySQL数据库root用户
  BOOL EnterMysqlRoot(char MysqldPath[], char completeMysql[]);
  //修改MySQL数据库root用户密码
  BOOL ModifyRootPassword(LPSTR lpModifyRootPwd);
  //执行控制台命令
  BOOL ExecDosCommand(LPTSTR lpCommandLine);
  //启动系统服务
  BOOL StartSystemService(LPCTSTR lpServiceName);


函数实现及调用
void CMySQLDlg::OnOK()
{
  LPSTR lpMysqld = new char[MAX_PATH];
  memset(lpMysqld, 0, MAX_PATH);

  char completePath[MAX_PATH] = {'"', 0};
  completePath[MAX_PATH - 1] = '\0';

  char MysqldPath[MAX_PATH] = {0};
  char completeMysql[MAX_PATH] = {'"', 0};
  completeMysql[MAX_PATH - 1] = '\0';

  LPSTR lpModifyRootPwd = new char[MAX_PATH];
  memset(lpModifyRootPwd, 0, MAX_PATH);

  if (!CheckPassword())
  {
    return;
  }
  if (!GetMysqlPath(lpMysqld))
  {
    return;
  }

  KillProcess("mysqld.exe");

  if (!SkipMysqlVerification(lpMysqld, completePath))
  {
    return;
  }
  if (!ExecDosCommand(completePath))
  {
    AfxMessageBox("跳过MySQL数据库安全验证失败");
    return;
  }
  if (!EnterMysqlRoot(MysqldPath, completeMysql))
  {
    return;
  }
  if (!ExecDosCommand(completeMysql))
  {
    AfxMessageBox("进入MySQL数据库root用户失败");
    return;
  }
  if (!ModifyRootPassword(lpModifyRootPwd))
  {
    return;
  }
  if (!ExecDosCommand(lpModifyRootPwd))
  {
    AfxMessageBox("重置MySQL数据库root用户密码失败");
    return;
  }
  if (!ExecDosCommand("flush privileges;"))
  {
    AfxMessageBox("刷新MySQL系统表权限失败");
    return;
  }
  if (!ExecDosCommand("quit"))
  {
    AfxMessageBox("退出MySQL数据库失败");
    return;
  }

  AfxMessageBox("MySQL数据库root用户密码重置成功");
}

void CMySQLDlg::OnCancel()
{
  CDialog::OnCancel();
}

BOOL CMySQLDlg::CheckPassword()
{
  //刷新控件值到对应变量
  UpdateData(TRUE);
  if (m_sPwd == m_sPwdAgain)
  {
    if (m_sPwd == "" && m_sPwdAgain == "")
    {
      AfxMessageBox("密码不能为空");
      return FALSE;
    }
    return TRUE;
  }
  AfxMessageBox("密码不一致,请重新输入");
  m_sPwd = "";
  m_sPwdAgain = "";
  UpdateData(FALSE);
  return FALSE;
}

BOOL CMySQLDlg::GetMysqlPath(LPSTR lpMysql)
{
  HKEY hKey;
  //MySQL数据库路径注册表项
  LPCTSTR RegMySQL = "SYSTEM\\ControlSet001\\Services\\Eventlog\\Application\\MySQL";

  if (ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegMySQL, 0, KEY_QUERY_VALUE, &hKey))
  {
    AfxMessageBox("您没有安装MySQL数据库");
    return FALSE;
  }

  //MySQL数据库路径注册表键值名称
  LPCTSTR lpKeyName = "EventMessageFile";
  //MySQL数据库路径注册表键值类型
  DWORD ValueType = REG_EXPAND_SZ;
  DWORD dwDate = MAX_PATH;

  if (ERROR_SUCCESS != ::RegQueryValueEx(hKey, lpKeyName, NULL, &ValueType, (LPBYTE)lpMysql, &dwDate))
  {
    AfxMessageBox("查询注册表失败");
    return FALSE;
  }

  ::RegCloseKey(hKey);
  return TRUE;
}

BOOL CMySQLDlg::ElevatedPermissions()
{
  HANDLE hToken;
  //得到进程的令牌句柄
  if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
  {
    TOKEN_PRIVILEGES tkp;
    //修改进程的权限
    if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
    {
      AfxMessageBox("修改进程权限失败");
      return FALSE;
    }
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    //通知操作系统修改进程权限
    AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL);
    return (ERROR_SUCCESS == GetLastError());
  }
  return FALSE;
}

BOOL CMySQLDlg::KillProcess(LPCSTR lpProcessName)
{
  if (!ElevatedPermissions())
  {
    AfxMessageBox("系统进程提权失败");
    return FALSE;
  }
  //创建当前系统的进程快照
  HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  PROCESSENTRY32 pe;
  pe.dwSize = sizeof(PROCESSENTRY32);

  //获取第一个进程的信息
  if (!Process32First(hSnapShot, &pe))
  {
    AfxMessageBox("获取进程信息失败");
    return FALSE;
  }

  CString strProcessName = lpProcessName;
  strProcessName.MakeLower();

  //循环获取下一个进程的信息
  while (Process32Next(hSnapShot, &pe))
  {
    //返回进程执行文件名
    CString scTmp = pe.szExeFile;
    scTmp.MakeLower();

    if (!scTmp.Compare(strProcessName))
    {
      //返回进程ID
      DWORD dwProcessID = pe.th32ProcessID;
      //打开一个已存在的进程对象,并返回进程的句柄
      HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
      //强制结束进程
      TerminateProcess(hProcess, 0);
      //关闭句柄
      CloseHandle(hProcess);
      return TRUE;
    }
    scTmp.ReleaseBuffer();
  }

  strProcessName.ReleaseBuffer();
  return FALSE;
}

BOOL CMySQLDlg::SkipMysqlVerification(LPSTR lpMysqld, char completePath[])
{
  char quotes[2] = {'"', '\0'};
  LPSTR lpParameter = " --skip-grant-tables &";
  if (!GetMysqlPath(lpMysqld))
  {
    return FALSE;
  }
  strcat(completePath, lpMysqld);
  if (lpMysqld != NULL)
  {
    delete[] lpMysqld;
  }
  strcat(completePath, quotes);
  strcat(completePath, lpParameter);
  return TRUE;
}

BOOL CMySQLDlg::EnterMysqlRoot(char MysqldPath[], char completeMysql[])
{
  char Mysql[] = "mysql.exe";
  char quotes[2] = {'"', '\0'};
  LPSTR lpParameter = " -u root";
  GetMysqlPath(MysqldPath);
  LPSTR lpMysqlBin = MysqldPath;
  LPSTR lpDelete = NULL;
  LPSTR lpStr = "mysqld.exe";
  int nLen = strlen(lpStr);
  while ((lpDelete = strstr(MysqldPath, lpStr)) != NULL)
  {
    strcpy(lpDelete, lpDelete + nLen);
  }
  strcat(completeMysql, lpMysqlBin);
  strcat(completeMysql, Mysql);
  strcat(completeMysql, quotes);
  strcat(completeMysql, lpParameter);
  return TRUE;
}

BOOL CMySQLDlg::ModifyRootPassword(LPSTR lpModifyRootPwd)
{
  char strRight[] = {"update mysql.user set password=PASSWORD('"};
  char strLeft[] = {"') where User='root';"};
  strcat(lpModifyRootPwd, strRight);
  strcat(lpModifyRootPwd, m_sPwd);
  strcat(lpModifyRootPwd, strLeft);
  return TRUE;
}

BOOL CMySQLDlg::ExecDosCommand(LPTSTR lpCommandLine)
{
  SECURITY_ATTRIBUTES sa;
  HANDLE hRead, hWrite;

  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  //使用系统默认的安全描述符
  sa.lpSecurityDescriptor =  NULL;
  //创建的进程继承句柄
  sa.bInheritHandle = TRUE;

  //创建匿名管道
  if (!CreatePipe(&hRead, &hWrite, &sa, 0))
  {
    return FALSE;
  }

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  ZeroMemory(&si, sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
  GetStartupInfo(&si);
  si.hStdError = hWrite;
  //新创建进程的标准输出连在写管道一端
  si.hStdOutput = hWrite;
  si.wShowWindow = SW_SHOW;
  si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

  //创建子进程
  if (!CreateProcess(NULL, lpCommandLine, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
  {
    return FALSE;
  }
  CloseHandle(hWrite);

  char buffer[4096] = {0};
  DWORD bytesRead;

  while (1)
  {
    if (NULL == ReadFile(hRead, buffer, 4095, &bytesRead, NULL))
    {
      break;
    }
    TRACE(buffer);
    Sleep(200);
  }

  return TRUE;
}

BOOL CMySQLDlg::StartSystemService(LPCTSTR lpServiceName)
{
  SC_HANDLE scSCM;
  SC_HANDLE scService;
  BOOL bRes = FALSE;
  //连接到服务控制管理器,并打开指定的数据库
  scSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

  if (scSCM)
  {
    //打开服务
    scService = OpenService(scSCM, lpServiceName, SC_MANAGER_ALL_ACCESS);
    if (scService)
    {
      bRes = StartService(scService, 0, NULL);
      if (bRes)
      {
        //ShowLastErrorMsg(_T( "启动服务 "));
        CloseServiceHandle(scService);
      }
      else
      {
        //ShowLastErrorMsg(_T( "启动服务 "));
        CloseServiceHandle(scSCM);
      }
    }
  }

  return bRes;
}

就是进行MySQL数据库后执行控制台命令怎么都不成功,请麻烦高手协助,100块钱不多,但我尽力了,谢谢!
我QQ:346102598
...全文
98 点赞 收藏 1
写回复
1 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zyq5945 2011-10-24
命令提示符是不能发消息的,因为它没有消息循环。
把多个命令写在批处理里,用"cmd.exe /c yourcmd.bat"来执行试试。
回复
相关推荐
发帖
数据库
创建于2007-09-28

3956

社区成员

VC/MFC 数据库
申请成为版主
帖子事件
创建了帖子
2011-10-24 10:00
社区公告
暂无公告